2014-11-14 2 views
0

В этом примере в Википедии (http://en.wikipedia.org/wiki/Closure_(computer_programming)) он утверждает, что при вызове переменной closure1 с closure1(3) будет возвращен 4. Может кто-то пройти через пример - я не понимаю.Закрытие - уточнение переменной и функции

function startAt(x) 
    function incrementBy(y) 
     return x + y 
    return incrementBy 

variable closure1 = startAt(1) 
variable closure2 = startAt(5) 

Invoking the variable closure1 (which is of function type) with closure1(3) will return 4, while invoking closure2(3) will return 8. While closure1 and closure2 are both references to the function incrementBy, the associated environment will bind the identifier x to two distinct variables in the two invocations, leading to different results. 

Если это помогает, вот мое настоящее понимание. variable closure1 = startAt(1) задает переменную closure1 функции startAt(), которая по умолчанию инициализируется значением 1. Однако вызов closure1(3) устанавливает это значение по умолчанию 3. То, что я тогда не понимаю, это то, откуда y.

variable closure1 = startAt(1) 
+0

Связанные: [Как работает закрытие JavaScript?] (Http://stackoverflow.com/questions/111102/how-do-javascript-closures-work) – apsillers

+0

Закрытие - это только классы бедных классов. Занятия - это просто плохие закрытия. – leppie

ответ

0

При запуске startAt, вы создать новую функцию. Каждый раз, когда вы запускаете startAt, вы создаете совершенно новую функцию. Таким образом, мы понимаем, что код

variable closure1 = startAt(1) 
variable closure2 = startAt(5) 

создает две различные функции и сохраняет их в colsure1 и closure2. Функция startAt похожа на фабрику, которая возвращает новые функции. Вы назвали его дважды и создали две функции. Эти две созданные функции хранятся внутри closure1 и closure2.

Вот что означает «закрытие»: каждая функция кариеса вокруг своего собственного переменная среда. Переменная среда - это набор внешних переменных, которые может видеть функция. Функция создает свою переменную среду при ее создании на основе всех переменных, находящихся в настоящее время в области. (Техническое определение закрытия является: «функциональным код плюс переменной окружения».)

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

Итак, первый звонок startAt(1) имеет переменную x, которая равна 1. Функция, созданная внутри этого вызова до startAt, имеет переменную среду, включающую в себя то, что x равно 1.

Функции могут иметь аргументы. В функциях, созданных startAt, каждый ожидает один аргумент y. Поэтому, когда вы вызываете x + y при вызове созданной функции, y предоставляется в качестве аргумента этим конкретным вызовом, а x предоставляется переменной средой этой функции. Когда вы вызываете closure1(3), значение аргумента y равно 3, а значение x (из переменной среды функции) равно 1, поэтому вы получаете результат 4.

Второй звонок startAt создает совершенно новую переменнуюx. Это x имеет значение 5.Функция, созданная этим вторым вызовом startAt, имеет другую переменную среду, которая включает в себя этот новый x, значение которого составляет 5. Когда вы вызываете эту вновь созданную функцию с closure2(3), у нас есть x=5 и y=3, поэтому x+y дает результат 8.

+0

Это я понимаю: «первый вызов startAt (1) имеет переменную _x_, равную 1." Этого я не делаю: «Функции, созданные startAt, каждый ожидает один аргумент, называемый _y_». Откуда взялась «у»? – Snowcrash

+0

@SnowCrash Из определения созданной функции: обратите внимание на 'y' in' function incrementBy (y) '. Аргументами являются функционально-локальные переменные (значениям которых присваивается время вызова функции). Указав формальный аргумент 'y', вы говорите:« Всякий раз, когда эта функция вызывается, ей будет предоставлено значение. Мы вызываем это значение «y'». – apsillers

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