(здесь разработчик V8 - поэтому я очень мало знаю о других браузерах / движках.)
На этот вопрос нет простого ответа; реализации сложны.
Строки в V8 всегда неизменяемы (после создания). Одна из причин заключается в том, что при размещении объектов в куче обычно нет свободного места после объекта, поэтому мы не можем просто добавлять символы в существующую строку. Другая причина заключается в том, что отслеживание того, какие строки могут быть безопасно мутированы, добавило бы необычайной сложности (помимо нескольких более простых для обнаружения нишевых случаев, но если бы поддерживались только они, то этот механизм обеспечил бы гораздо меньшую ценность).
В V8 есть несколько изящных уловок для манипуляций со строками в рукаве: когда вы берете подстроку из большей строки, никакие символы не копируются; новая строка - это просто ссылка, в которой говорится: «Я часть длины X той другой строки, начиная с индекса Y». Аналогично, при объединении двух строк, таких как ваш пример completeWorks
, новая строка является ссылкой, которая говорит: «Я - объединение этих двух других строк». (Для полноты я упомяну, что существует минимальное количество символов, ниже которого эти уловки не применяются, потому что простое копирование символов, по крайней мере, столь же эффективно.)
Числа более чувствительны к производительности, и с ними легче работать. чем струны. В общем, номера, размещенные в куче, всегда неизменны; но это не конец истории. V8 широко использует специальное представление для «Smis» («маленькие целые числа»), потому что многие числа в программах JavaScript попадают в эту корзину. Smis - это не куча объектов; создание нового так же дешево, как и его изменение, и фактически неотличимо (как int
в C ++). Для чисел вне диапазона Smi оптимизирующий компилятор также выполняет «escape-анализ» и может «распаковывать» неоткрывающиеся числа, что означает сохранение их в регистре ЦП (как простой 64-битный float) вместо того, чтобы размещать их в куче. во-первых, что снова даже лучше, чем изменение неизменяемых в противном случае объектов кучи. Для особого случая чисел, хранящихся в свойствах объекта, V8 также (в некоторых случаях) использует изменяемое хранилище.
Итак, ответ на ваш вопрос - «да» (например, при генерации неоптимизированного кода V8 не тратить время на выполнение анализа, поэтому код должен консервативно предполагать, что где-то нужно какое-то старое значение) и «нет» (для оптимизирующего компилятора ваша интуиция верна, что этого можно избежать; однако это все еще не означает что любые числа, которые были выделены в куче, будут там изменены).
Так как переменная i
ограничена l oop
Область действия JavaScript сложно. Во-первых, нет int i
. Теперь рассмотрим это:
for (var i = 0; i < 100; i++) {
// Use i here, or don't.
}
console.log(i); // Prints "100".
Если вы имели в виду let i
, то, конечно, у вас была бы переменная с блочной областью видимости. В этом примере производительность будет такой же.
У нас будет ненужная гонка между for l oop (создание новых значений i
в памяти) и сборщиком мусора (уничтожение все старые значения i
), которые l oop обычно выигрывает
Нет. Сборщик мусора очень адаптивен, в частности, он выполняет больше работы, когда происходит больше выделений. Нет возможности "обогнать" его. При необходимости выполнение программы останавливается, пока сборщик мусора пытается найти память, которую можно освободить.
, и у нас будет переполнение стека.
Нет, стек переполняется не имеют ничего общего с распределением объектов, сборкой мусора или кучной памятью в целом.