В javascript единственный способ создать новую переменную область видимости - это функция.
Необходимость новой области будет полностью зависеть от обстоятельств.Таким образом, общие примеры, которые вы представили, не дают однозначного ответа.
Чтобы дать что-то более конкретное, давайте возьмем ваш тест 2 и применим этот очень распространенный сценарий.где someoperations
- это асинхронный вызов, такой как setTimeout
:
for( var i=1; i<4; i++ ) setTimeout( function() { alert( i ); }, 1000 * i);
Проблема в том, что каждая функция, созданная в цикле (и переданная в setTimeout
), ссылаетсята же самая переменная i
, и поскольку она является setTimeout
, которая не является блокирующей, цикл завершается полностью, прежде чем какая-либо из функций, созданных в цикле, когда-либо будет вызвана.
В результате получаетсячто каждая функция будет предупреждать 4
, поскольку именно там после цикла оставалось значение i
.
Пример: http://jsfiddle.net/Ng3rr/
С другой стороны, если вы вызываете функцию внутри цикла , которая устанавливает setTimeout
, передавая значение i
этой функции, тогда переменная, на которую ссылается каждая функция, отправляется на setTimeout
будет местный inner_i
, который ссылается на Value, который был передан во внешний вызов.
(я назвал его inner_i
, чтобы различать два, но вы также можете назвать внутреннюю переменную i
.Это называется изменением теней.)
for( var i=1; i<4; i++ )(function( inner_i ){
setTimeout( function() { alert( inner_i ); }, 500 * inner_i);
})( i );
Теперь каждое предупреждение отображает значение, которое было получено во время каждой итерации.
Итак, как вы можете видеть, оно полностью зависит отситуация.
Пример: http://jsfiddle.net/Ng3rr/1/
Чтобы добавить некоторый контраст к приведенным выше примерам, если мы не выполняли какой-либо асинхронный код в цикле,внешняя функция была бы ненужной.
Это:
for( var i=1; i<4; i++ ) alert( i );
Пример: http://jsfiddle.net/Ng3rr/2/
... и это:
for( var i=1; i<4; i++ )(function( inner_i ){
alert( inner_i );
})( i );
Пример: http://jsfiddle.net/Ng3rr/3/
... будет иметь идентичное поведение, делая внешнюю функцию ненужной.
Таким образом, вызывая внешнюю функциюФункция создает новую переменную области видимости.В этой новой области видимости переменные будут сохраняться любыми дополнительными вложенными функциями, созданными в этой области.
Кроме того, хотя переменные, созданные в этой области, доступны в функциях, вложенных в эту область, они недоступен за пределами этой области.Это предотвращает загрязнение окружающей области с помощью дополнительных имен переменных.