Сегодня мне пришло в голову другое использование, поэтому я взволнованно искал в Интернете и нашел упоминание об этом: Определение переменных внутри области действия .
Фон
JavaScript, несмотря на внешнее сходство с C и C ++, не включает переменные в блок, в котором они определены:
var name = "Joe";
if ( true )
{
var name = "Jack";
}
// name now contains "Jack"
Объявление замыкания в цикле - обычная задача, которая может привести к ошибкам:
for (var i=0; i<3; ++i)
{
var num = i;
setTimeout(function() { alert(num); }, 10);
}
Поскольку цикл for не вводит новую область видимости, все три функции будут совместно использовать один и тот же num
со значением 2
.
Новая сфера: let
и with
С введением оператора let
в ES6 становится легко вводить новую область видимости, когда необходимо избежать этих проблем:
// variables introduced in this statement
// are scoped to each iteration of the loop
for (let i=0; i<3; ++i)
{
setTimeout(function() { alert(i); }, 10);
}
Или даже:
for (var i=0; i<3; ++i)
{
// variables introduced in this statement
// are scoped to the block containing it.
let num = i;
setTimeout(function() { alert(num); }, 10);
}
До тех пор, пока ES6 не станет универсально доступным, это использование будет ограничено новейшими браузерами и разработчиками, желающими использовать транспортеры. Однако мы можем легко смоделировать это поведение, используя with
:
for (var i=0; i<3; ++i)
{
// object members introduced in this statement
// are scoped to the block following it.
with ({num: i})
{
setTimeout(function() { alert(num); }, 10);
}
}
Цикл теперь работает так, как задумано, создавая три отдельные переменные со значениями от 0 до 2. Обратите внимание, что переменные, объявленные в блоке, не ограничиваются им, в отличие от поведения блоков в C ++ (в C переменные должны быть объявлены в начале блока, так что это похоже). Это поведение на самом деле очень похоже на let
блочный синтаксис , представленный в более ранних версиях браузеров Mozilla, но не получивший широкого распространения в других местах.