为什么在ES6中使用类绑定了对象创建的对象的方法?

时间:2016-12-13 17:50:37

标签: javascript class oop methods ecmascript-6

我喜欢ES6课程,但我无法理解为什么我必须在这样的构造函数中绑定方法:

constructor() {
    this.someMethod = this.someMethod.bind(this)
}

我几乎需要为任何方法做到这一点。

这是一个真正的限制还是我错过了什么?这背后的原因是什么?我知道JS中的类只是语法糖,但这可能是它们的一部分。

1 个答案:

答案 0 :(得分:10)

引用Mark Miller对the linked esdiscuss post的回答:

  

早期的几个类提议都是这样做的,因为它们从es5对象的语义开始,作为闭包和类作为实例组合的特征。

     

doku.php?do=search&id=traits

     

这个想法是语言支持会使这种语义有效,避免了每个实例为每个方法急切分配一个闭包的需要。

     

然而,由于我理解的原因,这些未能获得牵引力。相反,我们转向糖,将主要的es5模式编码类转换为原型继承。最初,我们试图让这纯粹是糖,这样人们就可以毫不费力地将这种主导模式中的代码重构为类。

     

当我们围绕超级和建筑的详细语义进行斗争时,es6类偏离了纯糖。但是这种偏差只能防止es6类的无痛重构成为主导的es5模式。实际上,将es5模式重构为es6类仍然没有任何意义。

     

zenparsing/es-function-bind#17,我们意识到了

     

我们仍然可以在提取时使用方法绑定 - 通过判断方法作为getter绑定的访问器安装在原型上来解释行为。然而,这种认识对于es6来说太迟了。因为它会使重构变成更危险的类 - 更多的是语义变化 - 即使我们及时想到它也不清楚它是否会飞行。相反,在装饰器设计的所有变体中,可以通过显式创建此访问器属性来编写这样的装饰器,以便装饰方法是绑定提取。然而(!),如果实现为用户土地装饰器,这比对象关闭更糟糕!在分配对象时,Objects-as-closures具有更高的分配成本。

     

jsperf.com/creating-stateful-objects

     

但是在创建对象后使用对象非常有效:

     

jsperf.com/strict-where-state

     

(请注意,jsperf错误地将Edge 28.14257.1000.0标识为Chrome 46.0.2486。这值得注意,因为Edge使用WeakMaps的转置表示,因此基于WeakMap的私有状态使用对Edge的惩罚要小得多。尽管如此除了这个主题之外。)

     

为了使提取绑定的装饰器有效,实现在某处需要某种特殊情况,以避免在立即调用方法时进行分配,而不是被观察提取。 TC39唯一需要做的就是标准化这样的装饰器,以便实现可以将它作为它们识别的内置提供。

凯文史密斯的回答:

  

一般来说,在使语言“更好”(对某些主观价值体系)和保持一致性之间往往存在紧张关系。我认为在这种情况下保持一致性是正确的。

也就是说,public class fields proposal将允许您将实例方法定义为

class Foo {
  someMethod = () => {
    // do stuff
  }
}

(而不是在constructor中执行相同操作。)