2015-01-12 4 views
0

У меня этот код.Путаница с закрытием в javascript

<body> 

<p>Counting with a local variable.</p> 

<button type="button" onclick="myFunction()">Count!</button> 

<p id="demo">0</p> 

<script> 
var add = (function() { 
    var counter = 0; 
    return function() {return counter += 1;} 
})(); 

function myFunction(){ 
    document.getElementById("demo").innerHTML = add(); 
} 
</script> 
</body> 

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

Означает ли это, что каждый раз, когда добавляется вызов, только возврат функции вызывается не всей функцией?

Если нет, может кто-нибудь объяснить это?

ответ

3

Да, возвращается только возвращаемая функция внутри IIFE при вызове функции add().

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

Единственное, что делает внешний IIFE, это держать переменную counter внутри собственной области.

IIFE == Immediately-invoked function expression

+0

Почему код не выполняется из первого утверждения функции, а скорее переходит непосредственно назад. Пожалуйста, дайте мне некоторое объяснение. – suman

+0

Внешняя функция - это IIFE, она немедленно вызывается, когда парсер сталкивается с ней, и возвращается результат, который в этом случае является другой функцией. – adeneo

+0

Я думаю, что страница wikipedia, с которой я связан, объясняет это довольно хорошо. – adeneo

1

В следующем коде, у вас есть функция, которая возвращает функцию:

var add = (function() { 
    var counter = 0; 
    return function() { 
     return counter += 1; 
    } 
})(); 

Внешняя функция немедленно выполняется. Таким образом, add присваиваются внутренней функция:

function() { 
    return counter += 1; 
} 

Как вы можете видеть, counter переменные во внутренней функции относится к контексту внешней функции (где counter объявлен). Этот контекст называется closure и по-прежнему упоминается во внутренней функции. Итак, JavaScript поддерживает этот контекст.

Как @RobG указывает, внутренние правила выполнения JavaScript больше похожи: идентификатор counter во внутренней функции первого решен во внутреннем контексте выполнения. Поскольку он не найден там, выполняется поиск следующего объекта в цепочке областей видимости, который является внешним контекстом выполнения, и там находится counter.

Таким образом, по магии закрытия переменная counter может быть доступна и изменена при вызове внутренней функции (с использованием add).

Итак, при вызове add вы выполняете внутреннюю функцию, которая закрывается над counter.

+1

Более подробное объяснение может быть: «идентификатор * счетчик * во внутренней функции сначала разрешен во внутреннем контексте выполнения. Поскольку он не найден там, выполняется поиск следующего объекта в цепочке областей видимости, который там находится внешний контекст выполнения и * счетчик *. Но, возможно, это только я. ;-) – RobG

+0

@RobG Это более подробное объяснение. Я добавил его к ответу. спасибо. –

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