Почему допустимо медленнее, чем var в цикле for в nodejs?

Я написал очень простой тест:

console.time('var');
for (var i = 0; i < 100000000; i++) {}
console.timeEnd('var')


console.time('let');
for (let i = 0; i < 100000000; i++) {}
console.timeEnd('let')

Если вы используете Chrome, вы можете попробовать его здесь (поскольку NodeJS и Chrome используют один и тот же движок JavaScript, хотя обычно немного разные версии):

// Since Node runs code in a function wrapper with a different
// `this` than global code, do that:
(function() {
  console.time('var');
  for (var i = 0; i < 100000000; i++) {}
  console.timeEnd('var')


  console.time('let');
  for (let i = 0; i < 100000000; i++) {}
  console.timeEnd('let')
}).call({});

Ответ 1

Основываясь на различии между механикой var и let, это связано с тем, что var существует во всей области блока анонимной функции, тогда как let существует только внутри цикла и должен быть повторно объявленным для каждой итерации. 1 Вот пример, демонстрирующий эту точку:

(function() {
  for (var i = 0; i < 5; i++) {
    setTimeout(function() {
      console.log(`i: ${i} seconds`);
    }, i * 1000);
  }
  // 5, 5, 5, 5, 5


  for (let j = 0; j < 5; j++) {
    setTimeout(function() {
      console.log(`j: ${j} seconds`);
    }, 5000 + j * 1000);
  }
  // 0, 1, 2, 3, 4
}());

Ответ 2

По этому вопросу. Я пытаюсь найти некоторый ключ формы хром V8 исходный код. вот код пилинга пика V8:

https://github.com/v8/v8/blob/5.4.156/src/compiler/loop-peeling.cc

Я пытаюсь это понять, я считаю, что для цикла имеет средний уровень в реализации. для цикла будет удерживать значение приращения в среднем слое.

Если использование цикла позволяет объявить "i" , V8 объявит новую переменную я для каждой итерации цикла, скопирует значение переменной приращения среднего уровня на эту новую объявленную "i" , а затем поместит ее в область тела цикла;

Если цикл использует var для объявления "i" , V8 будет только ссылаться на значение среднего значения среднего уровня для области тела цикла. Это уменьшит накладные расходы на производительность итерации цикла.

Извините за мой английский. В исходном коде v8 есть график, который покажет вам механизм.