2016-02-22 72 views
2

通常情況下,創建一個封閉,創建它的另一個功能裏面,它得到其父的範圍:是否有可能在Javascript中創建一個外部閉包?

var parent = function(){ 
    var a = "works!"; 
    var subfunction(){ 
    console.log(a); // "works!" 
    } 
    subfunction(); 
} 

我試圖想出一個辦法來模擬具有此功能關閉行爲被定義爲以外的父函數。我知道這是可能的使用參數:

var parent = function(){ 
    var a = "hello"; 
    subfunction(a); 
} 
var subfunction(a){ 
    console.log(a); // works, but because it's a param 
} 

我試圖找出是否有辦法做到這一點,而無需顯式設置的參數。我最初想我可以通過函數的本地對象作爲參數

var parent = function(){ 
    var a = "hello"; 
    subfunction(localScope); 
} 
var subfunction(localScope){ 
    console.log(localScope.a); // not going to work this way 
} 

...但因爲我已經發現it's impossible to get a reference to a function's scope。有沒有其他的方法來模擬函數的實際範圍之外的閉包?

+0

[可能感興趣](https://en.wikipedia.org/wiki/Scope_%28computer_science%29#Lexical_scope_vs._dynamic_scope) - JavaScript是一個詞彙範圍的語言。 – Pointy

回答

1

不,JS中的閉包始終是詞法的(即引用它們的父範圍)。

如果你想創建一個明確的設置環境封閉,你當然可以使用一個輔助函數,該函數:

function unrelated() { 
    var closure = makeClosure("hello"); 
    closure(); 
} 
unrelated(); 

function makeClosure(a) { 
    return function() { // closes only over `a` and nothing else 
     console.log(a); 
    } 
} 

這是接近一個,你會得到一個「外部封鎖」。請注意,您只能將值傳遞給makeClosure,而不是對局部變量的引用。當然,你可以製作對象並將它們傳遞給它們,並且使用with(不推薦!),你甚至可以使它們看起來像變量。

+0

這似乎與我的第二個例子幾乎完全一樣,除了不是將'a'作爲參數傳遞,而是將'a'的_value_作爲參數傳遞。 – brentonstrine

+0

@brentonstrine:區別(它使它更接近原始閉包)是當* *創建*函數時傳遞值,而不是*調用*時。 – Bergi

+0

這太可怕了,它是如何得到upvotes超越了我。是Bergi,這與他的第二個例子不同,但這不是他要求的,甚至不是遠程的。 – QBM5

相關問題