2010-12-04 2 views
2

Если у меня есть следующий код:укупорочные терминологии и семантический сомнения

function foo() 
{ 
    var a = []; 
    for(var i = 0; i < 3; i++) 
    { 
     a[i] = function(x) 
     { 
      return function() 
      { 
       return x; 
      } 
     }(i); 
    } 
    return a; 
} 

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

а затем выражение лямбда-это замыкание?

Спасибо.

ответ

1

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

Таким образом, функции, хранящиеся в a[i], закрылись вокруг их уникального x, который был в том же объеме, и, таким образом, имеют к нему доступ. Поскольку эта переменная доступна только этой функцией, которая была передана из функции self invoking, у вас есть закрытие.

Я хотел бы отметить, что было бы лучше, если бы вы не использовали самоназывающую анонимную функцию здесь, поскольку она не нужна и добавляет дополнительные служебные данные. Вместо этого объявите именованную функцию и вызовите ее.

function foo() 
{ 
    var a = []; 
    function retain_i(x) 
    { 
     return function() 
     { 
      return x; 
     } 
    } 
    for(var i = 0; i < 3; i++) 
    { 
     a[i] = retain_i(i); 
    } 
    return a; 
} 

EDIT: Чтобы быть более точным на ваш вопрос:

замыкание создается, когда я звоню (я) на каждой итерации ...

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

Если вы не вернули эту функцию, у вас не было бы закрытия.

Так как вы видите из примера модифицированного кода, который я дал, определение/объявление функции не создает замыкание. Скорее выполнение функции, которая выдает из нее какую-то другую функцию, имеющую доступ к недоступным другим переменным, создает закрытие.

+1

В соответствии с моделью среды закрытие создается * при определении функции *. Не имеет значения, переживает ли закрытие переживающий контекст или нет. – EFraim 2010-12-06 22:22:23

1

Закрытие создается, когда вы определяете функцию, а не когда вы ее запускаете - это называется лексическим охватом.

0

Закрытия создаются по определениям функций.

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

Результат, присвоенный ячейке i массива, - это функции, возвращающие i.

Другой плакат является правильным, назвав его «лексическим» охватом - большинство современных языков, похоже, его используют.

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