我正在尝试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
。我做错了什么?
答案 0 :(得分:28)
简短回答:this
指向最近的边界this
- 在所提供的代码中this
位于封闭范围内。
更长的答案:箭头函数在创建它们时绑定它们的 do not have this
this
, arguments
or other special names bound at all - 在创建对象时,在封闭中找到名称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
定义的范围相同的范围,而不是函数在添加到{时附加到的新范围。 {1}}对象。
你不能使箭头功能以这种方式工作,但正如@kamituel在his answer中指出的那样,你可以利用更短的方法声明模式在ES6中获得类似的空间节省:
person
答案 1 :(得分:22)
同意@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"
答案 2 :(得分:5)
接受的答案非常简洁明了,但我会详细说明肖恩·维埃拉所说的话:
箭头功能没有 这个论点或其他特殊名称都受到约束。
因为箭头函数没有“this”,所以它使用父级的“this”。 “this”始终指向父级,person对象的父级是Window(如果您在浏览器中)。
要证明它在你的控制台中运行:
var person = {
name: "Jason",
anotherKey: this
}
console.log(person.anotherKey)
你将获得Window对象。
我觉得这是一个非常有用的思考方式。这不是完整的故事,因为对象文字的“这个”是另一个讨论。
答案 3 :(得分:2)
这里函数内部的值取决于箭头函数的定义位置而不是它的使用位置。
所以this
指的是全局/窗口对象,如果没有包装在其他命名空间
答案 4 :(得分:0)
问题是(MDN)
箭头函数表达式[...]以词汇方式绑定此值。
箭头函数捕获封闭上下文的this值。
因此,该函数中this
的值将是您创建对象文字的this
的值。可能在非严格模式下为window
,在严格模式下为undefined
。
要解决此问题,您应该使用普通功能:
var person = {
name: "jason",
shout: function(){ console.log("my name is ", this.name) }
}
person.shout();