Ответ 1
Когда вы используете let
, тело цикла for должно создать новую область для обработки правильного времени жизни для переменной цикла, однако во многих случаях можно оптимизировать дополнительный код и время выполнения. Например, рассмотрите этот код:
let sum = 0;
let fns = [];
for (let i=0; i < 1000; i++) {
function foo() { sum += i; }
fns.push(foo);
}
Когда вы запускаете его через babeljs, вы можете видеть, что эквивалентный код ES5, который он производит, включает вызов функции, чтобы сохранить правильные сроки жизни переменных:
var sum = 0;
var fns = [];
var _loop = function _loop(i) {
function foo() {
sum += i;
}
fns.push(foo);
};
for (var i = 0; i < 1000; i++) {
_loop(i);
}
Однако babel достаточно умен, что, если вы не делаете ничего, что требует продления жизни переменной цикла, он просто использует обычный цикл for
с встроенным телом. Итак, ваш код:
for (let i=0; i < 1000; i++) {
true;
}
может быть показано, что он в точности эквивалентен:
for (var i=0; i < 1000; i++) {
true;
}
Я предполагаю, что что-то очень похожее происходит внутри Chrome, но они еще не оптимизировали случаи, когда им не нужно сохранять переменную цикла.
Было бы интересно посмотреть, как код, который я использовал в начале этого примера, сравнивается в Firefox и Chrome, поскольку я подозреваю, что оба они тоже будут медленными. Вы должны остерегаться синхронизации вещей, таких как пустые циклы, поскольку результаты могут быть искажены оптимизацией намного больше, чем обычно для реального кода.