2010-11-23 28 views
2

爲什麼函數中的自我調用函數沒有得到JavaScript中外部函數的作用域?Javascript中的自我調用函數的範圍

var prop = "global"; 

var hash = { 
    prop: "hash prop", 
    foo: function(){ 
     console.log(this.prop); 
     (function bar(){ 
      console.log(this.prop); 
     })(); 
    } 
}; 

var literal = { 
    prop: "object" 
}; 

hash.foo(); 
// hash prop 
// global 

hash.foo.call(literal); 
// object 
// global 

看起來像改變外部函數的作用域對內部自我調用函數的作用域沒有影響。

PS:問題不在於如何改變內部函數的範圍。但是,「Javascript語言」角度的恰當解釋是什麼?所有自執行函數默認情況下都具有「全局」範圍嗎?如果是這樣,爲什麼?

回答

1

當您調用內部函數時,您不會將任何對象作爲this上下文應用,因此默認情況下它將this設置爲window。如果你想打電話與同this作爲外部功能關閉,你就必須做到:

(function bar(){ 
    console.log(this.prop); 
}).call(this); 

或者:

var that = this; 
(function bar(){ 
    console.log(that.prop); 
})(); 
+0

+1爲第一個解決方案! – 2010-11-23 22:17:49

7

你的問題是this和它所引用:

foo: function(){ 
    console.log(this.prop); 
    (function bar(){ 
     console.log(this.prop); <--- this does not reference to foo here, but instead it refers to the window object 
    })(); 
} 

你需要保持到外this參考:

foo: function(){ 
    console.log(this.prop); 

    var that = this; 
    (function bar(){ 
     console.log(that.prop); <--- tada! 
    })(); 
} 

更新
一些解釋。這都是關於JavaScript在調用函數時如何確定上下文的。

function Test() { 
    this.name = "Test"; 
    this.bar = function() { console.log("My name is: "+ this.name);} 
} 

function Blub() { 
    this.name = "Blub"; 
    this.foo = function() { console.log("My name is: " + this.name);} 
} 

var a = new Test(); 
var b = new Blub(); 

// this works as expected 
a.bar(); // My name is: Test 
b.foo(); // My name is: Blub 

// let's do something fun 
a.foo = b.foo; // make an educated guess what that does... 

a.foo() // My name is: Test 

咦?我們是不是參考Blub的method?沒有,我們沒有。我們引用Blub的未綁定function

JavaScript綁定到.(點),並基於它決定值this應該是。

既然你沒有在一個對象上調用你的匿名函數(因此沒有.),它將使得this引用全局對象,在瀏覽器的情況下,它是窗口對象。

又如(有人可能認爲這會工作):

var str = "Hello World"; 
var ord = str.charCodeAt; // let's make a little shortcut here.... bad idea 

ord(0) // no dot... 

取而代之的是在str我們得到的是在全局對象的那些炭代碼,當然這不是一個字符串,因此charCodeAt撥打電話toString其結果爲"[object DOMWindow]"

+1

`this`將引用全局對象,而不是`bar`。 [更多信息](http://stackoverflow.com/questions/4223001/what-does-this-refer-to/4223037#4223037)。 – CMS 2010-11-23 22:15:50