2015-04-05 70 views
0

我有以下代碼:IIFE的這個變量是如何引用全球範圍的?

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

道格拉斯克羅克福德的Javascript:好的部分對我理解JS的函數範圍怪癖有很大的幫助。 http://it-ebooks.info/book/274/ – 2015-04-05 22:44:06

+0

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/這個很好的解釋。 – mrmcgreg 2015-04-05 22:54:00

回答

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"}); 
2

Javascript中的任何函數調用都會根據函數的調用方式重置值this。一個IIFE就是這樣一個函數調用。

所以,如果你不調用該函數的任何特殊方式,this值將在嚴格模式在瀏覽器常規模式或undefined設置爲window。這就是Javascript在進行正常函數調用時處理this的方式。

作爲許多人的驚喜,當您在Javascript中調用函數時,沒有「保留」當前值this的概念。如果要控制它,您必須將其稱爲一個特定的方法來設置值this

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); 
    } 
}; 

工作演示:

在代碼中,你可以通過使用.call()與IIFE像這樣保存的thishttp://jsfiddle.net/jfriend00/66cL4zt5/

的所有方式的概述見this referencethis已設置。

+0

增加了用'.call(this)'演示的jsFiddle。 – jfriend00 2015-04-05 23:15:52