【问题标题】:ES6 arrow function lexical this in V8V8 中的 ES6 箭头函数词法 this
【发布时间】:2015-03-17 17:56:15
【问题描述】:

我有以下使用胖箭头函数的 ES6 代码:

var test = {
  firstname: 'David',
  fn: function() {
    return ['one', 'two', 'tree'].map(() => this.firstname)
  }
}
console.log(test.fn())

根据箭头函数的工作方式,我希望 thistest 对象。 ES6Fiddle、Traceur 和 Firefox 产生预期的输出,即 ["David", "David", "David"]

但是,当使用 chrome://flags/#enable-javascript-harmony 在 Chrome 中启用这些功能时,我得到了 [undefined, undefined, undefined]。如果你console.log(this) 它表明它是窗口对象并且你在严格模式下得到一个错误。 ES6 箭头函数的词法 this 还没有在 V8 中实现吗?

【问题讨论】:

  • 在 FF 中工作得很好。我猜 Chrome 的实现仍然很草率。
  • 是的,this 在箭头函数中的绑定是 Chrome 目前最大的问题。在我们在兼容表中的测试中,它只实现了 9 个中的 4 个——kangax.github.io/compat-table/es6/#arrow_functions
  • 谢谢@kangax,应该马上去那里看!很高兴知道 - 太糟糕了,它使箭头函数在 V8 中变得不那么有用了。
  • :( 在带有--harmony 标志的Node 0.12 中存在同样的问题。

标签: javascript this v8 ecmascript-6 lexical-scope


【解决方案1】:

词法this 是 ES6 箭头函数在 v8 中的最后一部分,这也是它仍然落后于标志并且尚未准备好发布的原因。 Igalia 的 Adrian Perez 正在实现箭头功能,一旦解决了一些 TurboFan 问题,最终补丁几乎已经准备就绪:https://codereview.chromium.org/883823002/

【讨论】:

  • @kernel,箭头运输意味着他们的实施已经完成,所以问题不再存在。
  • @AlexandrSkachkov,事实上,即使没有标志,箭头也将在即将推出的 Chrome 45 中可用。
  • 谢谢@AlexandrSkachkov。最后要弄清楚的是,当这个来自 Chrome 45 的确切 V8 版本登陆 node / iojs 时。目前他们正在合并 V8 v4.5.89,但我不太了解这个版本背后的内容。 Chrome 43 似乎安装了 V8 4.3.61.30,因此看起来 Chrome 版本与 V8 版本控制的主要和次要版本一致。考虑到这一点,Chrome 45 应该实现 V8 v4.5.x,当 github.com/nodejs/io.js/pull/2091 被合并时问题应该得到解决。
  • 在此期间,此拉取请求已关闭,将在 io.js next+1 中可用。
  • @MörreNoseshine 如前所述,这已在 V8 4.5+ 中得到解决。这可能需要一些时间才能作为标签登陆 iojs。
【解决方案2】:

粗箭头是 ES6 的一个特性。它已在 Firefox(Gecko) 中引入,但尚未在其他浏览器中引入(尤其是在 V8 中还没有完全引入,这对于 nodejs/iojs 开发来说很有趣)。这是一个参考文档

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions#Browser_compatibility

无论如何,如果您需要范围绑定,那么请使用 bind() 而不是 =>。这是一个简单的例子。

而不是这个。

$("#example").on("click", () => {
   // your code goes here
});

使用这个。

$("#example").on("click", (function() {
   // your code goes here
}).bind(this));

如果您不需要范围绑定,那么只需这样做。

$("#example").on("click", function() {
   console.log("example");
});

【讨论】:

  • Arrows 在 V8 中已经完成,并且已经在没有标志的情况下发布了。 Chrome 45(即将推出测试版)将接手它们。
  • 我不确定参考文档是否真实。我更喜欢使用kangax.github.io/compat-table/es6/#chrome45