提问人:thank_you 提问时间:3/2/2015 最后编辑:hippietrailthank_you 更新时间:3/2/2022 访问量:25068
箭头函数和这个 [重复]
Arrow Functions and This [duplicate]
问:
我正在尝试 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
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);
}
};
在这里,函数内部的 this 值由箭头函数的定义位置决定,而不是使用箭头函数的位置。
因此,如果未包装在其他命名空间中,则引用全局/窗口对象this
同意@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"
评论
this
问题是(MDN)
箭头函数表达式 [...] 在词法上绑定 this 值。
箭头函数捕获封闭上下文的 this 值。
因此,该函数中的值将是创建对象文本的位置的值。可能,这将是非严格模式和严格模式。this
this
window
undefined
要修复它,您应该使用一个普通函数:
var person = {
name: "jason",
shout: function(){ console.log("my name is ", this.name) }
}
person.shout();
公认的答案非常好、简洁、清晰,但我会详细阐述一下肖恩·维埃拉所说的话:
箭头函数没有 这个参数或其他特殊名称完全绑定。
由于箭头函数没有“this”,因此它使用父函数的“this”。“this” 始终指向父对象,而 person 对象的父对象是 Window(如果您在浏览器中)。
要证明这一点,请在控制台中运行此命令:
var person = {
name: "Jason",
anotherKey: this
}
console.log(person.anotherKey)
你将获得 Window 对象。
我发现这是一种非常有用的思考方式。这并不是完整的故事,因为对象字面上的“这个”是什么是另一个讨论。
评论
this
在本例中为 Window。