Javascript ES6避免这种情况/自我

Javascript ES6避免这种情况/自我,javascript,highcharts,ecmascript-6,Javascript,Highcharts,Ecmascript 6,我试图使用es6避免“const that=this”、“const self=this”等。 然而,我正在与一些结合vue js和highcharts的构造进行斗争,在这些构造中,您得到了如下结果: data () { let that = this return { highchartsConfiguration: { ... big configuration ... formatter: function () { return t

我试图使用es6避免“const that=this”、“const self=this”等。 然而,我正在与一些结合vue js和highcharts的构造进行斗争,在这些构造中,您得到了如下结果:

data () {
  let that = this
  return {
    highchartsConfiguration: {
      ... big configuration ...
      formatter: function () {
        return this.point.y + that.unit
      }
    }
  }
}
如果可能的话,我希望在formatter对象中定义。使用arrow语法()=>{}将允许我从数据范围使用它,但我将失去赋予函数一个额外范围的能力


我不想修改使用过的库。

如果您需要调用
格式化程序
方法的
this
,则无法绕过额外的变量(
that
self
,无论什么).

该示例说明了在当前JS OOP实践之前出现的Highcharts和D3等旧库中存在的问题,这些库强烈依赖动态
上下文将数据传递给回调函数。问题的原因是数据没有像普通JS事件处理程序或jQuery回调中那样作为回调参数进行复制

预计将选择此
上下文(词汇或动态)中的一个,并将另一个指定给变量

所以

这是克服这个问题最常见、最简单的方法

然而,如果词法
this
是常规使用的,或者如果回调是作为
this
上下文绑定到类实例的类方法,则这是不实际的。在本例中,
可由开发人员指定,回调签名将更改为接受动态
上下文作为第一个参数

这是通过应应用于老式回调的简单包装函数实现的:

function contextWrapper(fn) {
    const self = this;

    return function (...args) {
        return fn.call(self, this, ...args);
    }
}
对于词法

data () {
  return {
    highchartsConfiguration: {
      formatter: contextWrapper((context) => {
        // `this` is lexical, other class members can be reached
        return context.point.y + this.unit
      })
    }
  }
}
...

constructor() {
  this.formatterCallback = this.formatterCallback.bind(this);
}

formatterCallback(context) {
    // `this` is class instance, other class members can be reached
    return context.point.y + this.unit
  }
}

data () {
  return {
    highchartsConfiguration: {
      formatter: contextWrapper(this.formatterCallback)
    }
  }
}
或者,对于类实例,作为

data () {
  return {
    highchartsConfiguration: {
      formatter: contextWrapper((context) => {
        // `this` is lexical, other class members can be reached
        return context.point.y + this.unit
      })
    }
  }
}
...

constructor() {
  this.formatterCallback = this.formatterCallback.bind(this);
}

formatterCallback(context) {
    // `this` is class instance, other class members can be reached
    return context.point.y + this.unit
  }
}

data () {
  return {
    highchartsConfiguration: {
      formatter: contextWrapper(this.formatterCallback)
    }
  }
}

如果您包括为什么它听起来不像一个X/Y问题,那么您可以使用
.bind(this)
函数(){返回this.point.Y+that.unit}.bind(this)
或者像`()=>{返回this.point.Y+that.unit}这样的箭头函数,@ShubhamKhatri
箭头函数不是ES6功能
?您也可以不使用该语言定义的类。正如Douglas Crockford所说,“ECMA团队有一千种用JavaScript实现类的方法。他们选择了一种比任何一种都糟糕的方法。”@ShubhamKhatri bind确实改变了我所知的上下文。我使用.bind(这个),那么它将与()=>{}相同。这并没有真正的帮助,因为我两者都需要。我在寻找类似函数(that=this){return that.unit+this.point.y}的东西,不幸的是它不起作用。我知道我需要一个额外的变量。我只想直接在函数中声明它,而不是在数百行之外。我希望有一个类似格式化程序的快捷方式:function(that=this){return that.unit+this.point.y}。。。想想看。。它可能会起作用,我会试试的。还不能确定副作用。@user1497119副作用是您仅限于
that=this
recipe,例如,您不能在ES.next中将
highchartsConfiguration
定义为类字段。另外,上下文杂耍使代码更难阅读。@user1497119您可以从IEFE创建
格式化程序
函数,以声明
在其定义处最大程度地接近,例如
格式化程序:(that=>函数(…){…this…})(this)
@Bergi,这正是我要寻找的。