Javascript.RU

Создать новую тему Ответ
 
Опции темы Искать в теме
  #1 (permalink)  
Старый 07.03.2011, 20:55
Интересующийся
Отправить личное сообщение для Goodfella Посмотреть профиль Найти все сообщения от Goodfella
 
Регистрация: 22.02.2011
Сообщений: 11

Вопрос по замыканиям
Добрый вечер друзья, возник вопрос, скорей даже не вопрос, а полная неразбериха по теме замыканий (недавно в JS). Что бы без длинных предысторий, сразу покажу код (взял из Википедии):
function createCounter() {
    var numberOfCalls = 0;
    return function() {
        return ++numberOfCalls;
    }
}
var fn = createCounter();
fn(); //1
fn(); //2
fn(); //3

Я понимаю, что этот код делает, но абсолютно не понимаю каким образом.
Почему при вызове функции createCounter() не обнуляется переменная numberOfCalls?
Зачем нужно копировать ссылку на функцию в переменную fn, почему ее нельзя вызвать напрямую?
Сам по себе, этот код меня не волнует, но это самый простой пример замыкания, который я, к сожалению, не могу понять. Я бы был очень благодарен, если бы вы подробно объяснили мне ситуацию, как это все считывает интерпретатор.
Ответить с цитированием
  #2 (permalink)  
Старый 07.03.2011, 20:59
Новичок на форуме
Отправить личное сообщение для Kolyaj Посмотреть профиль Найти все сообщения от Kolyaj
 
Регистрация: 19.02.2008
Сообщений: 9,177

Сообщение от Goodfella
Почему при вызове функции createCounter() не обнуляется переменная numberOfCalls?
Он обнуляется.

Сообщение от Goodfella
Зачем нужно копировать ссылку на функцию в переменную fn, почему ее нельзя вызвать напрямую?
Ссылка на функцию не копируется. Переменной fn присваивается результат работы функции createCounter().
Ответить с цитированием
  #3 (permalink)  
Старый 07.03.2011, 21:07
Интересующийся
Отправить личное сообщение для Goodfella Посмотреть профиль Найти все сообщения от Goodfella
 
Регистрация: 22.02.2011
Сообщений: 11

Сообщение от Kolyaj
Он обнуляется.
Меня ввел в недоумение метод alert(numberOfCalls), если его поставить перед
return ++numberOfCalls;

При каждом вызове функции, выводит увеличенный на единицу (по сравнению с предыдущим вызовом) результат, то есть - не обнуляется.
Ответить с цитированием
  #4 (permalink)  
Старый 07.03.2011, 21:40
Новичок на форуме
Отправить личное сообщение для Kolyaj Посмотреть профиль Найти все сообщения от Kolyaj
 
Регистрация: 19.02.2008
Сообщений: 9,177

При вызове функции createCounter обнуляется. Она у вас только один раз вызывается.
Ответить с цитированием
  #5 (permalink)  
Старый 07.03.2011, 21:53
Интересующийся
Отправить личное сообщение для Goodfella Посмотреть профиль Найти все сообщения от Goodfella
 
Регистрация: 22.02.2011
Сообщений: 11

Сообщение от Kolyaj
При вызове функции createCounter обнуляется. Она у вас только один раз вызывается.
Да, спасибо, я чуть-чуть посидел - разобрался с этим, но все же, если мы записываем в переменную fn именно значение возвращаемое функцией createCounter(), что значит fn()? Я это воспринимаю как "вызвать значение", что есть абсурд.
Ответить с цитированием
  #6 (permalink)  
Старый 07.03.2011, 21:54
Аватар для Aetae
Любитель
Отправить личное сообщение для Aetae Посмотреть профиль Найти все сообщения от Aetae
 
Регистрация: 02.01.2010
Сообщений: 5,384

Вот так будет работать как вы хотите, только это не имеет смысла))
function createCounter() {
    var numberOfCalls = 0;
    return function() {
        return ++numberOfCalls;
    }
}
var fn = createCounter;
fn()(); //1
fn()(); //1
fn()(); //1
__________________
29375, 35
Ответить с цитированием
  #7 (permalink)  
Старый 07.03.2011, 21:58
Новичок на форуме
Отправить личное сообщение для Kolyaj Посмотреть профиль Найти все сообщения от Kolyaj
 
Регистрация: 19.02.2008
Сообщений: 9,177

Сообщение от Goodfella
Я это воспринимаю как "вызвать значение", что есть абсурд.
Почему абсурд, если значением является функция? А createCounter возвращает функцию.
Ответить с цитированием
  #8 (permalink)  
Старый 07.03.2011, 22:13
Интересующийся
Отправить личное сообщение для Goodfella Посмотреть профиль Найти все сообщения от Goodfella
 
Регистрация: 22.02.2011
Сообщений: 11

Сообщение от Kolyaj
Почему абсурд, если значением является функция? А createCounter возвращает функцию.
Ага! То есть, фактически, fn() вызывает функцию
function() {
    return ++numberOfCalls;
}

Спасибо большое, вы очень помогли!
Если бы еще понять вот этот синтаксис, fn()(), который все таки вызывает фукцию createCounter(), но я думаю, это уже не так проблематично.
Ответить с цитированием
  #9 (permalink)  
Старый 08.03.2011, 00:09
Аватар для Aetae
Любитель
Отправить личное сообщение для Aetae Посмотреть профиль Найти все сообщения от Aetae
 
Регистрация: 02.01.2010
Сообщений: 5,384

var fn = createCounter;

Вот в чем дело, лол.)

А по поводу fn()() - ты это сколько угодно:
function џ() {
    return function() {
        return function() {
            return function() {
                return function() {
                    return function() {
                        return function() {
                            return function() {
                                alert('lol')
                            }
                        }
                    }
                }
            }
        }
    }
}
џ()()()()()()()()

хотя всё это фигнестрадание)
__________________
29375, 35
Ответить с цитированием
  #10 (permalink)  
Старый 08.03.2011, 01:29
Интересующийся
Отправить личное сообщение для Goodfella Посмотреть профиль Найти все сообщения от Goodfella
 
Регистрация: 22.02.2011
Сообщений: 11

Сообщение от Aetae
хотя всё это фигнестрадание)
Это ради понимания синтаксиса, не для решения конкретной задачи, но принцип уловил, спасибо.
Ответить с цитированием
Ответ



Опции темы Искать в теме
Искать в теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Вопрос по учебнику Invis1ble Сайт Javascript.ru 12 21.03.2011 19:06
Вопрос по работе функций в PHP bayah Серверные языки и технологии 2 12.02.2011 16:42
Теоретический вопрос. gods33 (X)HTML/CSS 10 16.12.2010 22:49
мааленький вопрос по Regexp:) mirniy Общие вопросы Javascript 1 22.01.2009 19:47
вопрос по long poll megaswin AJAX и COMET 2 27.05.2008 08:20