【发布时间】:2016-01-28 00:35:11
【问题描述】:
我正在使用 Babel 转译一个 ES2015 类:
class Foo {
constructor(foo) {
this.foo = foo;
}
sayFoo() {
console.log(this.foo);
}
}
如果我说像fooVar.sayFoo() 这样的话,这个类的工作方式完全符合我的预期。但是,如果我尝试将方法视为典型的 JavaScript 函数并将其作为参数 (element.click(fooVar.sayFoo)) 传递,则当方法实际运行时,其词法 this 是事件对象,而不是 Foo 的实例,所以this.foo 未定义。
相反,由于我指定了Foo 的实例,我希望fooVar.sayFoo 绑定到fooVar 的值。我必须编写一个额外的包装函数才能按预期工作。
我试图查看 ES6 规范,但无法弄清楚范围规则。根据规范,这种奇怪的作用域行为是正确的,还是某个地方的错误(例如,在 Babel 中)?
【问题讨论】:
-
那里没有魔法,函数的
this值取决于执行上下文,即它是如何被调用的,而不是它是如何定义的,总是有,与 ES2015 无关。当引用这样的函数时,元素被设置为this值。 -
不用写额外的包装函数,可以使用bind developer.mozilla.org/en/docs/Web/JavaScript/Reference/…
element.click(fooVar.sayFoo.bind(fooVar)) -
@adeneo 由于整个“类”系统是新的,我希望表达式
fooVar.sayFoo已经绑定到fooVar——在我看来,约瑟夫发布的替代方案应该是自动行为。我将把它归结为更多的 JavaScript 特质;谢谢。 -
有类或无类无关紧要,Babel 可能会将其转换为对象文字,但执行上下文仍然是设置
this值的原因,其他任何事情都会破坏互联网,想想所有带有将停止工作的引用函数的事件处理程序。 -
类系统并不是真的那么新,我认为它主要是在旧原型东西之上的语法糖。
标签: javascript class ecmascript-6