为什么不在ES6中用类绑定的对象的方法? [英] Why aren't methods of an object created with class bound to it in ES6?

查看:136
本文介绍了为什么不在ES6中用类绑定的对象的方法?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我喜欢ES6类,但是我不明白为什么我必须在这样的构造函数中绑定方法:

 构造函数(){
this.someMethod = this.someMethod.bind(this)
}

我需要做这个几乎任何方法。



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

解决方案

引用Mark Miller的回答< a href =https://esdiscuss.org/topic/why-are-es6-class-methods-not-automatically-bound-to-the-instance =nofollow noreferrer>链接的esdiscuss帖子这里:


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



doku.php?do = search& id = traits



这个想法是语言支持会使这个语义高效,避免需要每个方法急切地分配一个关闭。



然而,由于我的理解,这些没有得到牵引。相反,我们走向糖,将主要的编码类的es5模式转化为原型继承。最初,我们试图将这纯粹是糖,以便人们可以将这种主导模式的代码无痛地重构为课程。



当我们与超级和建设,es6类偏离纯糖。但是,这种偏差只能防止从es6类到无法重构es6模式的主导。实际上,将es5模式重构为es6类仍然是无痛的。



zenparsing / es-function-bind#17 我们实现了



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



jsperf.com/creating-stateful-objects



但一旦创建对象,使用对象就非常有效:



jsperf.com/strict-where-state



(请注意,jsperf将边缘28.14257.1000.0误认为Chrome 46.0.2486,值得注意的是,Edge使用WeakMaps的转置表示,因此基于WeakMap私有状态的使用对Edge的惩罚要小得多,虽然这是除了线程之外的一点。)



为了使装订器具有更高的绑定效率,实施需要某种特殊情况来避免在方法被立即调用时的分配,而不是可观察地提取编辑。 TC39唯一需要做的就是实现这一点,就是标准化这样的装饰器,以便实现可以将其作为它们识别的内置函数来提供。


而凯文史密斯的回答:


一般来说,让语言更好(对于某些主观价值体系)并保持一致性。我认为在这种情况下保持一致性是正确的。







公共类字段 提案将允许您将实例方法定义为

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

构造函数中执行相同的操作)。


I like ES6 classes but I can't understand why I do have to bind methods in constructors like this:

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

I need to do this almost for any method.

Is this a real limitation or am I missing something? What is the reason behind this? I know that classes in JS are only syntactic sugar but this could have been part of them.

解决方案

Quoting Mark Miller's answer to the linked esdiscuss post here:

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.

And Kevin Smith's answer:

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.


That said, the public class fields proposal will allow you to define instance methods as

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

(instead of doing the same in the constructor).

这篇关于为什么不在ES6中用类绑定的对象的方法?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆