2013-03-01 2 views
1
function f() { 
    function makeClosure(x) { 
    return function(){ 
     return x; 
    } 
    } 
    var a = []; 
    var i; 
    for(i = 0; i < 3; i++) { 
    a[i] = makeClosure(i); 
    } 
    return a; 
} 

var gg = f() 
gg[1]() 

Я так близко к пониманию закрытия. Я могу попробовать его:) ... Я получаю механику, у меня все еще есть немного проблем с концептуализацией.понимание замыкания в петлях

Я уверен, что это упрощение большого времени, но в приведенном выше правильном ли оно правильно думать о том, что происходит следующим образом?

  1. функция е() называется
  2. функция makeClosure вызывается и определяется индекс аргумента [1]
  3. функция makeClosure вызывает анонимную функцию и дает ей индекс аргумента [1]
  4. для начала заявление
  5. для заявления итерации затем вызывает функцию makeClosure
  6. функция makeclosure затем проверяет, если индекс аргумента [0] соответствует аргументу анонимной функции в
  7. функция makeClosure и анонимные функции не совпадают
  8. цикла повторяются второй раз производя индекс аргумента [1]
  9. функции makeclosure затем проверяет, является ли индекс аргумента [1] соответствует рассуждению анонимной функции в
  10. они матч
  11. функция makeClosure закрывается, а функция F() возвращает вар а, который в данный момент сохраненным в количестве 1

Извините, если это долго наматывается, я просто хочу, чтобы мое понимание не полностью испорчен. Спасибо!

+0

Так много информации о закрытии. Вы что-то застряли? Этот сайт предназначен для «моего кода - foo, я ожидаю, что он бат, он возвращает летучую мышь - что случилось?» – AlienWebguy

+0

только новичок, желающий дважды проверить с профи на мое понимание. Приносим извинения, если мой вопрос не входит в сферу применения этого сайта. – user2117138

+0

Эм, есть некоторые ошибки в вашей методологии. Нет никакого «вызова» какой-либо анонимной функции до начала 'for'. Нет совпадений индексов, а просто передаются аргументы вокруг и разные IIFE, возвращаемые внутри разных контекстов выполнения, которые работают из-за лексической области. –

ответ

1

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

If a function is declared within another function as opposed to invoked (this is an important distinction), the inner function has access to the scope of the function it is declared in.

Теперь к специфике этого вопроса. Все, что появилось после пункта 6, похоже, что это для другого кода, чем в настоящее время. Поэтому я просто опишу, что делает цикл.

Петля идет от 0 до 2, заполняя массив функциями. В рамках этих функций они соответственно имеют значения 0, 1 и 2. Поэтому в последней строке gg[1]() функция с индексом массива 1 возвращает значение 1.

Еще один способ концептуализации заключается в том, что во время цикла создается объект с свойством x. Этот объект имеет один безымянный метод, который возвращает x.

Надеюсь, это даст вам некоторое представление о том, что такое закрытие. Лично мне нравится думать о закрытии как правило определения и не обязательно как о типе объекта.

+0

Спасибо MushinNoshin, я предполагаю, что эта линия относится к тому, что я получаю от «Цикл идет от 0 до 2, заполняя массив функциями». Где хранится этот массив? Внутри анонной функции? И если да, то когда начинается цикл? когда функция f() вызывается? – user2117138

+0

Этот цикл выполняется как часть вызова f(). Этот массив хранится как часть области f(). Когда вызывается f(), внутренние элементы создаются заново, и когда они закончены, они фактически оставляют область видимости, если на них еще не ссылается что-то. Если мы будем следовать этой линии допроса, мы начнем собирать сбор мусора :) – MushinNoShin

0
  1. функции F() называется

Во-первых, среда для глобального кода устанавливается и декларации для f и gg обрабатываются.Затем оператор присваивает gg, что вызывает вызов f.

2. функция makeClosure вызывается и дается аргумент index [1]

Пока нет. Функция вызывается после запуска цикла (# 5).

Когда f называется новый контекст выполнения создается и создъм его окружение, makeClosure, a и i создаются как локальные переменные, глобальный объект находится на его видимости. Затем a назначен новый массив empy.

3. функция makeClosure вызывает анонимную функцию и дает ей аргумент index [1]

Звонок внутри makeClosure.

4. для заявления начинается . 5. для заявлений итерации затем вызывает функцию makeClosure

Это происходит до 2.

makeClosure называется первоначально со значением 0.

Когда вызывается makeClosure, создается новый контекст выполнения. Он имеет один формальный параметр x, которому присвоено значение 0 в первый раз, 1 второе и так далее.

В цепочке областей действия для makeClosure имеется объект выполнения для f, поэтому он имеет доступ ко всем параметрам и переменным f. Идентификаторы с именем Самеда «сглажены» локальными.

При каждом вызове makeClosure возвращает объект функции, который не имеет переменных или формальных параметров. Эти объекты функций имеют цепочку областей видимости, которые определены в момент их создания и включают в себя сами, а затем экземпляр контекста выполнения makeClosure, затем f, а затем глобальный контекст выполнения.

Возвращаемый функциональный объект присваивается члену a.

6. функция makeclosure затем проверяет, соответствует ли аргумент index [0] аргументу анонимной функции 7. функция makeClosure и анонимные функции не соответствуют 8. цикл повторяется второй раз, создавая индекс аргумента [1] 9. функция makeclosure затем проверяет, соответствует ли аргумент index [1] аргументу анонимной функции 10. они соответствуют 11.вызывается функция makeClosure и функция f() возвращает var a, которая в данный момент сохраняется как номер 1

Ничего из этого не происходит. Для каждого цикла новый вызов makeClosure выполняется так, что новая функция возвращается с другим экземпляром объекта выполнения в своей цепочке областей видимости. Они назначаются членам a.

Цикл for выполняет итерацию 3 раза, где i имеет значение 0, 1 затем 2. Когда i добирается до 3, он выходит перед выполнением.

12. Ссылка на массив (a) возвращается и назначается глобальному g.

13. g[1]. Это ссылается на вторую возвращаемую функцию, которая затем вызывается. Когда идентификатор x внутри этой функции разрешен по своей цепочке областей видимости, найден x внутри экземпляра makeClosure, который его создал. Это соответствует той, которая создана со значением 1, так что x имеет значение 1, которое возвращается.

Я, наверное, что-то испортил, но это более или менее то, что происходит.

+0

Спасибо за подробный ансверт Роб - очень полезно! – user2117138

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