2013-01-16 25 views
2

「[JavaScript函數]在內部存儲它們可能引用的變量,這些變量在其封閉範圍中定義。」確定JavaScript關閉中可訪問的變量集

我怎樣才能確定這組變量是什麼?

例如,大衛·赫爾曼在有效的JavaScript給出了這樣的功能(和關閉):

function sandwichMaker() { 

    var magicIngredient = "peanut butter"; 

    function make(filling) { 
     return magicIngredient + " and " + filling; 
    } 

    return make; 
} 

var f = sandwichMaker(); 

document.writeln("<p>" + f("jelly") + "</p>"); 
document.writeln("<p>" + f("bananas") + "</p>"); 
document.writeln("<p>" + f("marshmallows") + "</p>"); 

當然,magicIngredient是可變的訪問,使(),但還有什麼?如果sandwichMaker本身就是一個功能呢?然後是全局變量。當它在當前範圍內查找相關值時,它的功能是什麼?

+0

我得說,這是混淆了填充VAR如何被設置爲果凍因爲香蕉和棉花糖看起來並不像sandwichMaker()需要參數 –

+1

@nathanhayfield:但'make'確實 – Bergi

回答

1

如果sandwichMaker本身是一個函數呢?然後是全局變量。

是的,父函數的所有變量都是可訪問的(如果它們沒有被映射)。然後,範圍最高的函數從全局範圍繼承。

當它在當前範圍內查找相關值時,看什麼函數?

您可以用調試器檢查。在make中插入debugger;聲明,然後執行它並查看您的devtools。你會看到這樣的事情:

Scope Chain 
    0. make (currently executed): 
     this: (+)Window 
     arguments: (+)Arguments 
     filling "jelly" 
    1. sandwichMaker: 
     arguments: (+)Arguments 
     magicIngredient: "peanut butter" 
     make: (+)Function 
    Global 
     AnonXMLHttpRequest: … 
     ApplicationCache: … 
     Array: … 
     … 

也看看這篇大文章:http://dmitrysoshnikov.com/ecmascript/es5-chapter-3-2-lexical-environments-ecmascript-implementation/

例視圖在瀏覽器Devtools:

http://briangrinstead.com/files/scope-variables.png

(從www.briangrinstead.com

+0

謝謝,這似乎是唯一可能的答案。我希望有如下簡單的東西:for(prop in obj)記錄任何東西,但我會學習這個更復雜的技術。鏈接的文章也很好看。 –

+0

不,您無法確定在運行時 - 變量環境無法從程序訪問。 – Bergi

0

假設上述function sandwichMaker()有定義的變量...

var something = 'something'; 
function sandwichMaker() { 
... 

您可以從內sandwichMaker(),並從內部make()訪問something

可以從函數內訪問外部變量。如果您要在make()範圍內設置var something = 'something else',那麼您將在make()函數本身內實際上隱藏外部var something。但是,您可以設置something = 'something else',並且該值在所有範圍內都會更改。它只會隱藏值,如果你再次聲明該變量。

1

JavaScript使用功能範圍。這很容易理解 - 在函數中聲明的任何東西都具有該函數的作用域以及任何更高級的作用域。

閉合可被認爲是兩件事情組合在一起的:一個特定的範圍,在特定時間點(當創建函數)。

當然,magicIngredient是一個可以訪問make()的變量,但其他什麼是 ?

凡是是的make在其創建時間範圍訪問。這包括make函數中的所有變量以及任何更高級的範圍。製造的範圍據說是已關閉的它創建時的時間範圍,始終允許它訪問magicIngredient

如果sandwichMaker本身是一個函數呢?

然後make將有權訪問該範圍(因爲它在make創建時)也是如此。

然後是全局變量。在當前範圍內的相關值看起來 的功能是什麼?

解釋器將在當前執行的範圍內搜索任何引用的變量。如果它找不到它們,它會看到下一個更高的範圍。它會繼續看起來越來越高,直到找到變量或超出範圍(全局範圍最高,也就是運行在瀏覽器中的javascript的window對象)。

一個相關的概念是陰影 - 兩個變量可以在父/子範圍相同的名稱,孩子說是「影子」父,因爲它會優先考慮。注意這是一個不好的做法。

瞭解封閉和範圍界定工作的最簡單方法是瞭解簡單的工廠模式,如this one。當內部函數被創建並返回時,它在那個時間點被綁定到該範圍,並且即使在值不再存在之後,它仍將繼續提醒正確的值。

希望這有助於 - 很多問題塞進一個問題:)

+0

謝謝。我仍在努力理解關閉的影響,並且您的迴應有所幫助。但我真正的問題是一個實際的問題:我在這個職能範圍內 - 我必須與哪些方面合作? Bergi的迴應有助於回答這個問題。 –