我有以下代码:
var myObject = {
foo: "bar",
func: function() {
var self = this;
console.log("outer func: this.foo = " + this.foo);
console.log("outer func: self.foo = " + self.foo);
(function() {
console.log("inner func: this.foo = " + this.foo);
console.log("inner func: self.foo = " + self.foo);
}());
}
};
输出:
outer func: this.foo = bar
outer func: self.foo = bar
inner func: this.foo = undefined
inner func: self.foo = bar
我理解这是因为IIFE this
指的是全球范围,而不是myObject
。但为什么它涉及全球范围? IIFE的this
变量如何引用全局范围?
答案 0 :(得分:3)
因为这就是JS功能的工作方式。如果您未隐式(通过object.method()
语法)或明确(通过.call
,.apply
或.bind
)设置this
的值,则默认为全局对象,除非你处于严格模式。
因此,如果您使用IIFE并使用.call
,将其传递给另一个对象,则会将该对象作为this
值。
(function() {
console.log("inner func: this.foo = " + this.foo); // "bar"
console.log("inner func: self.foo = " + self.foo);
}).call({foo: "bar"});
答案 1 :(得分:2)
Javascript中的任何函数调用都会根据函数的调用方式重置this
的值。 IIFE就是这样一个函数调用。
因此,如果您不以任何特殊方式调用该函数,this
的值将在浏览器中以常规模式设置为window
或undefined
in严格模式。这就是Javascript在进行正常函数调用时处理this
的方式。
令许多人感到惊讶的是,没有"保留"在Javascript中调用函数时this
的当前值。如果你想控制它,你必须以特定的方式调用它来设置this
的值。
在您的代码中,您可以使用this
与IIFE一起保留.call()
的值,如下所示:
var myObject = {
foo: "bar",
func: function() {
var self = this;
console.log("outer func: this.foo = " + this.foo);
console.log("outer func: self.foo = " + self.foo);
(function() {
console.log("inner func: this.foo = " + this.foo);
console.log("inner func: self.foo = " + self.foo);
}).call(this);
}
};
工作演示:http://jsfiddle.net/jfriend00/66cL4zt5/
有关this
设置的所有方式的摘要,请参见this reference。