Javascript-форум (https://javascript.ru/forum/)
-   Общие вопросы Javascript (https://javascript.ru/forum/misc/)
-   -   Подскажите, как работает простой код (замыкание функции)? (https://javascript.ru/forum/misc/6501-podskazhite-kak-rabotaet-prostojj-kod-zamykanie-funkcii.html)

Dotod 30.11.2009 21:32

Подскажите, как работает простой код (замыкание функции)?
 
[ js ]
uniqueID = (function() { // Значение сохраняется в объекте вызова функции
var id = 0; // Это частная переменная, сохраняющая свое
// значение между вызовами функции
// Внешняя функция возвращает вложенную функцию, которая имеет доступ
// к этому значению. Эта вложенная функция сохраняется
// в переменной uniqueID выше.
return function() { return id++; }; // Вернуть и увеличить
})(); // Вызов внешней функции после ее определения
[ /js ]

Каким образом в переменную uniqueID попадает 0,1,2,3... при каждом вызове внешней функции (). Не понимаю. Ведь id постоянно обращается в ноль при вызове

subzey 30.11.2009 22:16

Повторно запускается не сама функция, а функция, которую функция вернула. Соответственно, получается, что порожденная функция берет значение из неумершей области данных создателя.
Подробнее почитайте в справочнике на этом сайте, он действительно хорош.

Dotod 30.11.2009 22:43

Я сейчас читаю книгу Носорог, которая здесь на первом месте в списке - норм бук. Если так как ты сказал, то все встает на свои места. Однако почему при первом вызове компилятор вызывает именно внешнюю (первую) функцию, а не вложенную. А при последующих вложенную. Не логично как-то ;)

subzey 01.12.2009 11:42

Может, опечатка?
По-идее, код сводится к чему-то типа этого:
var myCounter = createCounter();
myCounter();
myCounter();
myCounter();

или так:
createCounter()() /* именно ()() ! */

Dotod 01.12.2009 23:51

Если интересно, то этот код приведен на стр. 160 Книга с носорогом Подробное руководство Дэвид Флэнаган. Опечаток еще не находил. Меня прям озадачил этот пример

e1f 02.12.2009 03:03

Да нет там никакой опечатки. После выполнения блока из #1 у нас uniqueID содержит ссылку на функцию
function(){
    return id++;
}

При этом scope первой функции живет благодаря замыканию, и в результате последовательные вызовы
uniqueID()
uniqueID()
...
uniqueID()

Дайт последовательное увеличение каунтера.
Почитайте http://javascript.ru/basic/closure, там все хорошо описано.


Часовой пояс GMT +3, время: 06:45.