javascript - 为什么在 ES6 中不使用绑定(bind)到它的类创建的对象的方法?

标签 javascript class oop methods ecmascript-6

我喜欢 ES6 类,但我不明白为什么我必须在构造函数中绑定(bind)方法:

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

我几乎需要为任何方法执行此操作。

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

最佳答案

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

Several of the early class proposals did so, as they were starting with the semantics of es5 objects-as-closures and classes as compositions-of-instance-traits.

doku.php?do=search&id=traits

The idea was that language support would make this semantics efficient, avoiding the need to eagerly allocate a closure per method per instance.

However, for reasons I understand, these failed to gain traction. Instead, we moves towards sugar for the dominant es5 pattern of encoding classes into prototype inheritance. Initially, we tried to have this purely be sugar, so that people could painlessly refactor code in that dominant pattern into classes.

As we wrestled with the detailed semantics around super and construction, es6 classes deviated from being pure sugar. But this deviation only prevents painless refactoring from es6 classes into the dominant es5 pattern. Practically, it remains painless to refactor from the es5 pattern into es6 classes.

At zenparsing/es-function-bind#17 we realized

we could still have had methods bind on extraction -- accounting for the behavior by decreeing that methods are installed on the prototype as accessors whose getter binds. However, this realization came too late for es6. Since it would have made the refactoring into classes more hazardous -- more of a semantic change -- it is not clear it would have flown even if we had thought of it in time. Instead, under all variations of the decorator designs, one can write such a decorator so that decorated methods are bind-on-extraction, by explicitly creating this accessor property. However(!), if implemented as a user-land decorator, this has much worse performance than objects-as-closures!! Objects-as-closures have higher allocation cost when allocating the object.

jsperf.com/creating-stateful-objects

But are quite efficient at using the object once the object is created:

jsperf.com/strict-where-state

(Note that jsperf is misidentifying Edge 28.14257.1000.0 as Chrome 46.0.2486. This is worth noting because Edge uses the transposed representation for WeakMaps, and so WeakMap-based usage of private state has much less penalty on Edge. Though this is besides the point of this thread.)

To make a decorator for binding-on-extraction efficient, an implementation would need some kind of special case somewhere to avoid the allocation when the method is being immediately invoked, rather than being observably extracted. The only thing TC39 needs to do to enable this is to standardize such a decorator so that implementations can provide it as a builtin that they recognize.

凯文史密斯的回答:

In general, there is often a tension between making the language "better" (for some subjective value system) and maintaining consistency. I think maintaining consistency was the right call in this case.


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

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

(而不是在构造函数中做同样的事情)。

关于javascript - 为什么在 ES6 中不使用绑定(bind)到它的类创建的对象的方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41127519/

相关文章:

javascript - 检查是否选中任何复选框,如果没有,则显示错误

javascript - 正则表达式尝试将除特定模式之外的任何内容与允许的模式中的字符进行匹配

c++ - 推送到自定义堆栈类卡住 .exe

python - 类实例作为静态属性

java - java5 之前的版本 : Singleton pattern: Double checked Locking vs Static factory method

javascript - 如何在contenteditable div中找到插入符号前后的字符长度?

javascript - 简单 : replace div with ajax content (jquery)

java - 使用 toString 的建议

c++ - 如何修复错误 C2679 : binary '>>' : no operator found which takes

c# - 如果重写的方法返回不同的值,是否违反了里氏原则?