【问题标题】:ES6 arrow functions not working on the prototype?ES6 箭头函数在原型上不起作用?
【发布时间】:2015-10-23 15:57:36
【问题描述】:

当 ES6 箭头函数似乎不适用于使用prototype.object 将函数分配给对象时。考虑以下示例:

function Animal(name, type){
 this.name = name;
  this.type = type;
  this.toString = () => `${this.name} is a ${this.type}`;

}
var myDog = new Animal('Max', 'Dog');
console.log(myDog.toString()); //Max is a Dog

在对象定义中显式使用箭头函数有效,但使用 Object.prototype 语法的箭头函数无效:

function Animal2(name, type){
  this.name = name;
  this.type = type;
}
Animal2.prototype.toString = () => `${this.name} is a ${this.type}`;

var myPet2 = new Animal2('Noah', 'cat');
console.log(myPet2.toString()); //is a undefined

作为概念证明,使用带有 Object.prototype 语法的模板字符串语法确实有效:

function Animal3(name, type){
  this.name = name;
  this.type = type;
}
Animal3.prototype.toString = function(){ return `${this.name} is a ${this.type}`;}

var myPet3 = new Animal3('Joey', 'Kangaroo');
console.log(myPet3.toString()); //Joey is a Kangaroo

我是否遗漏了一些明显的东西?我觉得示例 2 应该在逻辑上工作,但我对输出感到困惑。我猜这是一个范围界定问题,但我被输出“is a undefined”吓跑了。

ES6 Fiddle

【问题讨论】:

  • @Bergi 我的问题是 10 个月前发布的,有 0 人支持。它怎么可能与 5 个月前发布的问题重复,为什么现在决定这一点很重要?
  • 这里没有责备(注意我也没有关闭问题,只是发表了评论)。唯一重要的是,未来的读者会被定向到关于这个主题的非常有用的规范帖子,这就是我链接它的原因。

标签: javascript prototype ecmascript-6 arrow-functions


【解决方案1】:

箭头函数提供了一个词法this。它使用在评估函数时可用的this

它在逻辑上等同于(以下不是有效代码,因为您不能拥有名为 this 的变量):

(function(this){
   // code that uses "this"
 })(this)

在您的第一个示例中,箭头函数位于构造函数中,this 指向新生成的实例。

在您的第三个示例中,未使用箭头函数,标准 this 行为一如既往地工作(函数范围内的 this)。

在您的第二个示例中,您使用箭头函数,但在评估它的范围内,this 是全局/未定义的。

【讨论】:

  • 那么是不是不能在构造函数之外使用箭头函数(示例2)?
  • 您可以在this 是您想要的this 的任何地方使用它。例如,假设您的对象有一个 setup() 函数,该函数为其自身添加了多个函数,您可以这样称呼它:myObj.setup()。该函数可以使用箭头函数来添加所需的函数。另一个更典型的用例是使用需要访问初始上下文的this 的回调函数。
  • "箭头函数提供了词法 this" 更准确的说法是箭头函数不提供 this,所以它不是从它自己的词法范围来自外部词法范围。
  • 我认为它更等同于function(){}.bind(this)。它预先绑定到创建它的范围的this。这在例如事件侦听器,我们经常希望在侦听器内部使用周围范围内的东西。在 es5 代码中,这意味着在附加侦听器或使用 bind 之前执行 var me = this
  • “它使用在评估函数时可用的this。” 具有误导性。建议:“它使用创建函数的上下文中存在的this。” 或者更好:“箭头函数根本没有自己的this 。它们关闭创建它们的上下文的this,就像关闭创建它们的变量一样。(它们还关闭arguments和相关的super。)“
【解决方案2】:

常规函数返回对当前 JavaScript 对象的引用,而箭头函数返回对全局窗口对象的引用。

常规函数可以很好地处理使用 new 关键字的对象。它们具有 constructor 函数,通过该函数可以在对象创建期间初始化值。可以使用原型链进行管理,但箭头函数没有构造函数,原型链。它们不能很好地处理对象。它们不能与分配内存的 new 关键字一起使用。

在您的第一个示例中,您在常规函数中编写箭头键函数,然后您将获得输出。

function Animal2(name, type){
    this.name = name;
    this.type = type;
}
Animal2.prototype.toString = function(){
    return () => `${this.name} is a ${this.type}`;
}

var myPet2 = new Animal2('Noah', 'cat');
console.log(myPet2.toString()()); //Noah is a cat

参考:Difference between regular function and arrow key function

【讨论】:

    猜你喜欢
    • 2023-02-10
    • 1970-01-01
    • 1970-01-01
    • 2019-01-06
    • 1970-01-01
    • 2020-05-09
    • 1970-01-01
    • 2016-09-07
    • 2022-01-21
    相关资源
    最近更新 更多