Проблема с глобальными переменными состоит в том, что компилятор не может знать, будет ли доступ к контенту «внешними» функциями (т. Е. Когда тело не известно во время компиляции).
Например console.log
может (теоретически) изменить varCounter
, если это глобальная переменная.Затем переменная должна быть сохранена в полном слоте Javascript (способном содержать строки, массивы, объекты) и затем считывать данные из нее для выполнения приращения.
Если переменная вместо этого локальная, доступ невозможен, еслиvar не захватывается, и поэтому сама переменная может быть оптимизирована, и цикл может просто обнаружить шаблон и увеличить 32-битное целое число в качестве индекса, не выделяя полный слот Javascript.
Если переменная являетсяfunction-local var
однако все по-другому, потому что внешняя функция к ним тоже не может получить доступ.В этом случае выполнение может быть даже быстрее с var
, чем с let
, если компилятор недостаточно умен: причина в том, что если в теле переменная потенциально захвачена замыканием, новая ячейка замыкания должна быть выделена вкаждая итерация.Этого не происходит с var
, поскольку область видимости - это целая функция (а не тело цикла for
):
x = [];
for (let i=0; i<10; ++) {
x.push(()=>i);
}
console.log(x[4]()); // Shows 4
изменяя let
на var
в вышеуказанном цикле, вывместо этого получим 10, потому что все замыкания захватывают одну и ту же var
ячейку.