我喜欢ES6类,但我不明白为什么要在构造函数中绑定方法:
constructor() {
this.someMethod = this.someMethod.bind(this)
}
几乎对于任何方法,我都需要这样做。
这是一个真正的限制,还是我遗漏了什么?这背后的原因是什么?我知道JS中的类只是语法糖,但这可能是它们的一部分。
发布于 2016-12-14 06:41:06
引用马克·米勒对the linked esdiscuss post的回答:
早期的几个类提案做到了这一点,因为它们从es5对象的语义开始-作为闭包,将类作为实例的组合特征。
的想法是,语言支持将使这种语义更有效,避免急切地为每个方法每个实例分配闭包。然而,出于我所理解的原因,这些都没有获得吸引力。取而代之的是,我们转向了将类编码为原型继承的主导es5模式。最初,我们试图让它纯粹是糖,这样人们就可以轻松地将主导模式中的代码重构为类。当我们纠结于关于超级和构造的详细语义时,es6类偏离了纯粹的糖。但是这种偏差只会阻止从es6类到主要的es5模式的轻松重构。实际上,从es5模式重构到es6类仍然很轻松。在zenparsing/es-function-bind#17,我们意识到我们仍然可以在提取时绑定方法--通过决定将方法作为其getter绑定的访问器安装在原型上来说明行为。然而,对于es6来说,这种认识来得太晚了。因为这会使重构到类中变得更加危险--更多的是语义上的变化--即使我们及时考虑到它,也不清楚它是否会飞起来。相反,在装饰器设计的所有变体中,通过显式地创建此访问器属性,可以编写这样的装饰器,以便装饰器方法是在提取时绑定的。但是(!),如果作为用户端装饰器实现,这比对象即闭包的性能差得多!!作为闭包的对象在分配对象时具有更高的分配成本。jsperf.com/creating-stateful-objects,但在对象创建后使用对象时非常有效:jsperf.com/strict-where-state (请注意,jsperf将Edge 28.14257.1000.0错误识别为Chrome46.0.2486。这是值得注意的,因为边缘使用WeakMaps的转置表示,因此基于WeakMap的私有状态的使用对边缘的惩罚要小得多。虽然这不是本主题的重点。)要使绑定到提取的装饰器有效,实现需要某种特殊情况,以避免方法被立即调用时的分配,而不是明显地被提取。要实现这一点,TC39需要做的唯一一件事就是标准化这样的装饰器,以便实现可以将其作为可识别的内置来提供。
凯文·史密斯的回答是:
一般而言,在使语言“更好”(对于某些主观价值系统而言)和保持一致性之间经常存在紧张关系。我认为在这种情况下保持一致性是正确的决定。
也就是说, proposal将允许您将实例方法定义为
class Foo {
someMethod = () => {
// do stuff
}
}
(而不是在constructor
中执行相同的操作)。
https://stackoverflow.com/questions/41127519
复制相似问题