箭头函数和 this

IT技术 javascript this ecmascript-6 arrow-functions
2021-02-03 05:53:07

我正在尝试 ES6 并希望在我的函数中包含一个属性

var person = {
  name: "jason",

  shout: () => console.log("my name is ", this.name)
}

person.shout() // Should print out my name is jason

但是,当我运行此代码控制台时,只记录my name is. 我究竟做错了什么?

5个回答

简短回答:this指向最近的边界this- 在提供的代码this中找到封闭范围。

更长的答案:箭头函数 this在创建时绑定它们 没有thisarguments或结合其它特殊名字-正在创建对象时的名称this是在封闭的范围内,没有找到person对象。您可以通过移动声明更清楚地看到这一点:

var person = {
  name: "Jason"
};
person.shout = () => console.log("Hi, my name is", this);

当翻译成 ES5 中箭头语法的模糊近似时,就更清楚了:

var person = {
  name: "Jason"
};
var shout = function() {
  console.log("Hi, my name is", this.name);
}.bind(this);
person.shout = shout;

在这两种情况下,this(对于shout 函数)都指向与person定义相同的作用域,而不是函数被添加到person对象时附加到的新作用域

不能让箭头函数以这种方式工作,但是,正如@kamituel 在他的回答中指出的那样,你可以利用 ES6 中较短的方法声明模式来获得类似的空间节省:

var person = {
  name: "Jason",
  // ES6 "method" declaration - leave off the ":" and the "function"
  shout() {
    console.log("Hi, my name is", this.name);
  }
};
箭头函数称为 lambda 表达式
2021-03-13 05:53:07
getify 链接失效了,可以在web.archive.org/web/20160625172303/http://blog.getify.com/查看...
2021-04-02 05:53:07

同意@Sean Vieira - 在这种情况下this绑定到全局对象(或者,如评论中所指出的,更一般地绑定到封闭范围)。

如果您想要更短的语法,还有另一个选择——增强的对象字面量支持属性函数的简短语法。this将按照您的预期绑定在那里。shout3()

window.name = "global";

var person = {
    name: "jason",

    shout: function () {
        console.log("my name is ", this.name);
    },
    shout2: () => {
        console.log("my name is ", this.name);
    },
    // Shorter syntax
    shout3() {
        console.log("my name is ", this.name);
    }
};

person.shout();  // "jason"
person.shout2(); // "global"
person.shout3(); // "jason"
@Oriol 是的,注意到 - 我认为这是顶级代码。谢谢!
2021-03-14 05:53:07
赞成,但注意this不一定是全局对象。
2021-04-05 05:53:07

接受的答案非常好,简洁明了,但我将详细说明 Sean Vieira 所说的话:

箭头函数根本没有绑定此参数或其他特殊名称。

因为箭头函数没有“this”,它使用父的“this”。“this”总是指向父对象,而person对象的父对象是Window(如果你在浏览器中)。

为了证明它在你的控制台中运行:

var person = {
    name: "Jason",
    anotherKey: this
}
console.log(person.anotherKey)

您将获得 Window 对象。

我发现这是一种非常有用的思考方式。这不是完整的故事,因为对象字面量的“this”是另一个讨论。

太棒了 - 我试图理解为什么它会发生这么多时间!!!!
2021-03-26 05:53:07
解释的很清楚。谢谢。
2021-04-02 05:53:07

这里函数内部 this 的值取决于箭头函数的定义位置,而不是它的使用位置。

因此this,如果未包装在其他命名空间中,则引用 global/window 对象

问题是(MDN

箭头函数表达式 [...] 在词法上绑定 this 值。

箭头函数捕获封闭上下文的 this 值。

因此,该this函数中的值将是this您创建对象字面量的位置的值可能,这将window处于非严格模式和undefined严格模式。

要修复它,您应该使用普通函数:

var person = {
  name: "jason",
  shout: function(){ console.log("my name is ", this.name) }
}
person.shout();