2017-02-01 3 views
1

Вот коды:JavaScript закрытие и сфера

function fn() { 
 
    var x = 1; 
 

 
    function fn2() { 
 
    x++; 
 
    console.log(x); 
 
    } 
 
    return fn2; 
 
} 
 
var foo = fn(); 
 
var bar = fn(); 
 
foo(); //2 
 
bar(); //2 
 
foo(); //3

У меня проблема, что я не могу понять, почему результат не .Я имею в виду, согласно принципу закрытия, foo и bar должны поддерживать объем функции fn, поэтому я думал, что foo и bar имеют одинаковые x. Надеюсь, вы поможете мне решить проблему.

ответ

1

foo и bar не имеют одинакового размера x. x создается, когда вызывается fn. Поэтому каждый звонок до fn создаст совершенно новый x, который будет доступен определенной функцией fn2, которая будет возвращена.

Чтобы проверить, что foo и bar не одни и те же x, вот пример:

function fn() { 
 
    var x = 1; 
 

 
    function fn2() { 
 
    x++; 
 
    return x; 
 
    } 
 
    return fn2; 
 
} 
 
var foo = fn(); 
 
var bar = fn(); 
 
console.log("foo: " + foo()); 
 
console.log("bar: " + bar()); 
 
console.log("foo: " + foo()); 
 
console.log("foo: " + foo()); 
 
console.log("foo: " + foo()); 
 
console.log("foo: " + foo()); 
 
console.log("bar: " + bar());

0

В вар х создает приватную переменную, она создается заново каждый раз Fn(). Если вы хотели его перенести, просто изменить уаг х к this.x:

fn = (function() { 
 
    this.x = 1; 
 

 
    function fn2() { 
 
    this.x++; 
 
    console.log(this.x); 
 
    } 
 
    return fn2; 
 
}); 
 
var foo = fn(); 
 
var bar = fn(); 
 
foo(); //2 
 
bar(); //3 
 
foo(); //4

+0

Я озадачен. На что это должно ссылаться здесь? Это будет 'undefined' в строгом режиме, а в противном случае - оконный объект. Это то же самое, что и объявление глобальной переменной 'x'. Кроме того, я предполагаю, что вы имеете в виду «каждый раз, когда' fn() '** называется **, а не« назначен ». –

+0

' this.x' будет делать 'x' глобальным. Это как если бы' x' был определен вне ' fn' (глобально). Итак, мы больше не говорим о закрытии. –

+0

Да, я возился и понял, что вы абсолютно правы. Вернитесь к чертежной доске ... – Snowmonkey

1

Вы должны вызвать первую функцию один раз, и построить замыкание над x затем возвращает функцию с функция внутри.

var fn = function() {   
 
    var x = 1; 
 
    return function() { 
 
     return function() { 
 
      x++; 
 
      console.log(x); 
 
     }; 
 
    }; 
 
}(); 
 

 
var foo = fn(); 
 
var bar = fn(); 
 
foo(); //2 
 
bar(); //3 
 
foo(); //4

0

Эти две такие же вызов, поэтому 2 при вызове их:

var foo = fn(); 
var bar = fn(); 

Оба установить var x=1 в частном порядке. Поэтому, когда вы вызываете их снова foo(); //3, внутренняя функция fn2 является той, которая вызывается с помощью оператора инкремента

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