.call应该如何为ES6箭头函数工作(根据标准)

How is .call supposed to work for ES6 Arrow Functions (according to the standards)?

本文关键字:工作 函数 标准 ES6 call      更新时间:2023-09-26

我正在使用ES6的交叉编译器(Babel,很快会是TypeScript),它目前不支持用=>语法生成的函数的正确.call行为;当我用.call调用它们时,它们的this值仍然是我第一次创建它们时它们从父作用域继承的值,而不是我用.call传递进来的第一个参数。

这是他们故意的行为吗,按照ES6标准(这将是非常令人失望的)?或者这只是交叉编译器的限制?

规范如下:

ArrowFunction没有为arguments、super、这个,或者new.target。任何对参数、super、this或的引用新的。ArrowFunction中的target必须解析为

。它固定在定义它的上下文中。你不能动态地改变它。特别是function。prototype。call上面写着:

如果func是一个箭头函数或绑定函数,则thisArg将被步骤5中的[[Call]]函数忽略。

如果您使用下面的methodical函数,它将创建一个方法,其中this作为回调的第一个参数传入。这样,您就拥有了胖箭头语法的所有好处(隐式返回,this不会在随后的函数调用中丢失),但仍然可以将其作为方法使用。当然也有简写的方法语法,它基本上是创建一个传统的es5风格的函数(略有不同,因为它不能用new调用)。

const methodical = func => function(...args) {
  return func(this, ...args)
}
const add = methodical(
  (instance, name, value) => (instance[name] = value, instance)
)
const a = {
  add
}
a.add('first', 1.23).add('second', 2.74)
add.call(a,'third', 3.11)
console.log(JSON.stringify(a, null, 2))

使用es2015速记方法代替

const b = {
  add(name,value) {
    this[name] = value
    return this
  }
}
b.add('first',1).add('second',2)
console.log(JSON.stringify(b))