我正在尝试 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
. 我究竟做错了什么?
我正在尝试 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
. 我究竟做错了什么?
简短回答:this
最近边界处的点this
- 在提供的代码this
中可以在封闭范围内找到。
更长的答案:箭头函数
根本没有绑定或其他特殊名称this
-arguments
当创建对象时,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
(对于喊函数)都指向与定义相同的范围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);
}
};
同意@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"
公认的答案非常好,简洁明了,但我将详细说明 Sean Vieira 所说的内容:
箭头函数根本没有绑定这个参数或其他特殊名称。
因为箭头函数没有“this”,所以它使用了父函数的“this”。"this" 始终指向父对象,而 person 对象的父对象是 Window(如果您在浏览器中)。
为了证明它在您的控制台中运行:
var person = {
name: "Jason",
anotherKey: this
}
console.log(person.anotherKey)
您将获得 Window 对象。
我发现这是一种非常有用的思考方式。这还不是完整的故事,因为对象文字的“this”是另一个讨论。
这里函数内部 this 的值取决于箭头函数的定义位置,而不是它的使用位置。
所以this
如果没有包装在其他命名空间中,则指全局/窗口对象
问题是(MDN)
箭头函数表达式 [...] 在词法上绑定 this 值。
箭头函数捕获封闭上下文的 this 值。
因此,该this
函数中的值将是this
您创建对象文字的位置的值。可能,这将window
处于非严格模式和undefined
严格模式。
要修复它,您应该使用普通函数:
var person = {
name: "jason",
shout: function(){ console.log("my name is ", this.name) }
}
person.shout();