2015-11-20 2 views
5

Допустим, мы определили этот function в глобальном масштабе:Заключительная часть яваскрипта затворов я стил не понимаю

function createCounter() { 
    var counter = 0; 

    function increment() { 
    counter = counter + 1; 

    console.log("Number of events: " + counter); 
    } 

    return increment; 
} 

В большинстве примеров, объясняющих затворов я вижу исполняющего:

createCounter(); 

из глобальный охват просто вернет внутреннюю функцию:

function increment() { 
    counter = counter + 1; 

    console.log("Number of events: " + counter); 
} 

Теперь, е, из-за этой линии в createCounter объявлении функции

return increment; 

Так что мой вопрос, почему это:

var counter1 = createCounter(); 

counter1(); 

Number of events: 1 //result 

Наконец получить функцию для работы?

По существу не counter1 и createCounter оба указателя на эту внутреннюю функцию, которые существуют в глобальном масштабе?

Возможно, лучший способ задать вопрос, почему именно counter1() работает, а не только возвращает внутреннюю функцию, например, createCounter?

+1

* «По существу не' counter1' и 'createCounter' как указатели на эту внутреннюю функцию» * No. 'counter1' относится к' приращению функции() 'который явно отличается от функции function createCounter()'. Вы можете легко проверить это, сравнив их: 'counter1 === createCounter' является' false'. Иначе говоря: 'createCounter' возвращает новую/другую функцию, она не возвращается сама. –

ответ

3

No, createCounter - это функция, которая возвращает отдельный экземпляр функции increment, удерживающей новое закрытие с другой локальной переменной counter.

Так что да, вам нужен дополнительный звонок, чтобы получить отдельный экземпляр функции и позвонить столько раз, сколько пожелаете. Обратите внимание, что вызов createCounter не увеличивает счетчик, но вызов counter1 или counter2 действительно увеличил его.

var counter1 = createCounter(); //local counter is still 0 
var counter2 = createCounter(); 
counter1(); // 1 
counter2(); // 1 
counter1(); // 2 
counter2(); // 2 
2

createCounter() возвращает вам функцию без ее вызова.

Вы также можете позвонить createCounter()() без необходимости в промежуточной переменной.

Если вы имели выход консоли во внешней функции, как это было бы понятнее, что происходит:

function createCounter() { 
    console.log("in createCounter"); 

    var counter = 0; 

    function increment() { 
     counter = counter + 1; 

     console.log("Number of events: " + counter); 
    } 

    return increment; 
} 

При вызове createCounter() и сохранить результат в переменной вы получите выход «в createCounter ", но НЕ" Количество событий ". Когда вы вызываете функцию, хранящуюся в переменной, вы получаете «Количество событий: 1», но НЕ «в createCounter».

1
  1. В функции JS являются objects типа Function.
  2. createCounter находится в глобальном масштабе, но increment нет.
  3. Когда вы вызываете createCounter(), он возвращает функцию, которая существует в 'createCounter function scope and there is another variable counter` в этой области.

  4. Поэтому, когда вы вызываете возвращаемую функцию, которую вы назвали counter1, как counter1(), она вызывается, которая затем увеличивает счетчик и регистрирует результат.

1

Если вы делаете console.log(counter1), он собирается распечатать функцию, поскольку это просто указатель на функцию.

Когда делать counter1(), вы призываете самой функцию