2014-12-26 93 views
0

我已經通過實施例7將以下代碼登載在以下的答案讀取How do JavaScript Closures work?更新靜態變量

function newClosure(someNum, someRef) { 
    // Local variables that end up within closure 
    var num = someNum; 
    var anArray = [1,2,3]; 
    var ref = someRef; 
    return function(x) { 
     num += x; 
     anArray.push(num); 
     alert('num: ' + num + 
      '\nanArray ' + anArray.toString() + 
      '\nref.someVar ' + ref.someVar); 
     } 
} 
obj = {someVar: 4}; 
fn1 = newClosure(4, obj); 
fn2 = newClosure(5, obj); 
fn1(1); // num: 5; anArray: 1,2,3,5; ref.someVar: 4; 
fn2(1); // num: 6; anArray: 1,2,3,6; ref.someVar: 4; 
obj.someVar++; 
fn1(2); // num: 7; anArray: 1,2,3,5,7; ref.someVar: 5; 
fn2(2); // num: 8; anArray: 1,2,3,6,8; ref.someVar: 5; 

我使用了相同的邏輯,用於我的例子

function increment() { 
    var id = 0; 
    return function(number) { 
     id += number; 
     alert('Unique ID: ' + id); 
    } 
} 

six = increment(); 
fourteen = increment(); 

six(6); 
fourteen(8); 

在這個例子我從中獲得靈感,

fn1(2); //num 7 

num輸出7因爲根據my und從前次呼叫第一次開始,它已被設置爲5。因此,使用相同的推理,我期望14(14)次調用返回14,因爲我相信ID會被更新爲6而不是0。爲什麼變量不是靜態的?我怎麼會說它是靜態的?

我也試着讓該函數設置一個數字參數,並將ID設置爲等於該參數,但沒有更新它。

http://jsfiddle.net/de9syawe/4/要顯示。

回答

2

newClosure的關閉將捕獲每次調用時初始化爲someNumnum。因此,f1有它自己的num,它開始於4,增加1到5,然後增加2到7。同時,f2有它自己的num,它開始於5,增加1到6,再次增加到2到8f1f2調用的交錯可能會讓您困惑,但它們是完全獨立的,並且不會共享任何變量。

以同樣的方式,increment構造的封閉將在值0處捕獲idsix具有id開始於0,增加6到6fourteen獨立地從它自己的0開始,並且增加8到8

比較:

var globalCounter = 0; 
function incrementWithGlobalCounter() { 
    var counter = 0; 
    return function(number) { 
     counter += number; 
     globalCounter += number; 
     alert('Counter: ' + counter + '; Global Counter: ' + globalCounter); 
    } 
} 

var one = incrementWithGlobalCounter(); 
var two = incrementWithGlobalCounter(); 

one(1); // 1, 1 
one(1); // 2, 2 
two(1); // 1, 3 
two(2); // 3, 5 
one(5); // 7, 10 

這裏,globalCounter由外罩捕獲,因此它是通過所有的內封共享; counter被內部封閉物和局部外部封閉物捕獲,所以它對於每個內部封閉物將是獨立的。

+0

非常感謝你@Amadan你說的對,我對f1和f2的調用感到困惑。這是一個愚蠢/愚蠢的忽略。我通過打電話14沒有意識到,我正在撥打另一個電話。 但是,還要感謝我展示globalCounter並讓我思考外部封閉! –