2014-12-26 3 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 

Количество выходов 7, потому что согласно моим данным он был установлен на 5 из предыдущего вызова в первый раз. Поэтому, используя те же рассуждения, я ожидал, что четырнадцать (8) вызовов возвратят число 14, потому что я полагал, что идентификатор был бы обновлен до 6, а не оставаться на 0. Почему переменная не статична? Как я могу объяснить, что он статичен?

Я также попытался установить функцию параметра числа и установить идентификатор, равный параметру, но также не обновляющий его.

http://jsfiddle.net/de9syawe/4/ для отображения.

ответ

2

Закрытие newClosure будет фиксировать num, инициализированное до someNum каждый раз, когда оно называется. Таким образом, f1 имеет свои собственные num, начинающийся с 4, увеличивается на единицу до 5, а затем увеличивается на 2 - 7. Между тем, у f2 есть своя num, которая начинается с 5, то увеличивается на 6, а еще раз на 8. Перемешивание звонков f1 и f2 может вас смутить, но они полностью разделены и не имеют никаких переменных.

В том же ключе закрытие, которое образует increment, будет содержать id по значению 0. six имеет id, начинающийся с 0, приращаясь от шести до 6. fourteen самостоятельно запускается самостоятельно 0 и увеличивается на восемь до 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. Это был глупый/глупый взгляд. Я не понимал, позвонив четырнадцать, я сделал другой звонок. Но спасибо за то, что он также показал мне globalCounter и заставило меня задуматься о внешнем закрытии! –

Смежные вопросы