2010-02-19 147 views
8

誰能解釋爲什麼結果是[20,20,10,10]在此代碼:javascript函數範圍

var x = 10; 
var foo = { 
    x: 20, 
    bar: function() { 
    var x = 30; 
    return this.x; 
    } 
}; 

console.log(
    foo.bar(), 
    (foo.bar)(), 
    (foo.bar = foo.bar)(), 
    (foo.bar, foo.bar)() 
); 

鏈接規格歡迎

+0

在IE看來輸出是20,20,undefined,undefined .. – RameshVel 2010-02-19 09:57:05

回答

7

不能指出你的規格,但我強烈推薦閱讀Douglas Crockford's "Javascript: The good parts"。本書將幫助您理解JavaScript的大部分奇怪但強大的功能。

作爲你的問題:

  1. foo.bar(),在bar功能 this關鍵字被綁定到對象foo
  2. (foo.bar)()是與上述相同,
  3. 在JavaScript中,您可以多次指定從右到左的變量

    z = 3; x =(y = z); console.log(x); // 3

函數作爲其他任何變量。因此,您將函數foo.bar分配給foo.bar,但括號會使分配的函數返回並執行。

(foo.bar = foo.bar)(); 
//is the same as 
var f = (foo.bar = foo.bar); 
f(); 
//and this also the same as: 
var f= foo.bar; 
f(); 

該函數返回從括號沒有綁定到任何東西,所以this將引用全局對象,在瀏覽器的情況下 - 在window對象。

4。該條款(foo.bar,foo.bar)()僅僅是相似:

a = (3, 4); //last value is returned, first just parsed. 
//a contains 4 

var f = (foo.bar, foo.bar); 
//f contains body of foo.bar function, 
f() // is executed in the context of `global` object, eg. `window`. 

請閱讀的JavaScript功能有關binding

0

我認爲以下question會有所幫助爲了這。

0

前兩個函數調用是等價的。他們在foo的範圍內調用foobar方法 - 因此this.x返回的值是foox屬性的值,即20

後面兩個調用都是有問題/無效的語法。試着通過JSLint運行你的代碼,你會發現它出現了幾個錯誤,然後完全窒息。我最好的猜測,爲什麼他們返回10是它試圖解析你的代碼的情況下,它真的不應該和困惑。 10可能會返回,因爲瀏覽器無法弄清楚您要做什麼,並且默認爲x的值爲10的全局(窗口)範圍。這也解釋了Ramesh Vel的評論,其中的第二個值在IE中出現爲undefined。由於語法無效,JavaScript的不同實現可能會以不同的方式處理它們。