В AS3 я считаю, что вы должны инициализировать все переменные вне циклов для повышения производительности. Это касается и JavaScript? Что лучше / быстрее / лучшие практики?
var value = 0;
for (var i = 0; i < 100; i++)
{
value = somearray[i];
}
или
for (var i = 0 ; i < 100; i++)
{
var value = somearray[i];
}
javascript
performance
davivid
источник
источник
Ответы:
Нет абсолютно никакой разницы в значении или производительности, в JavaScript или ActionScript.
var
это директива для парсера, а не команда, выполняемая во время выполнения. Если конкретный идентификатор был объявленvar
один или несколько раз где-нибудь в теле функции (*), тогда все использование этого идентификатора в блоке будет ссылаться на локальную переменную. Не имеет значения,value
объявлен ли онvar
внутри цикла, вне цикла или в обоих.Следовательно, вы должны написать то, что вы считаете наиболее читабельным. Я не согласен с Крокфордом в том, что ставить все переменные на вершину функции всегда лучше. Для случая, когда переменная временно используется в разделе кода, лучше объявить
var
в этом разделе, поэтому этот раздел стоит отдельно и может быть вставлен в копию. В противном случае скопируйте и вставьте несколько строк кода в новую функцию во время рефакторинга, не выделяя и не перемещая связанные элементы по отдельностиvar
, и вы получите случайную глобальную переменную.В частности:
Крокфорд порекомендует вам убрать второе
var
(или удалить обаvar
с иvar i;
выше), и jslint за это вам захочет. Но ИМО более приемлемо, чтобы сохранить обаvar
, сохраняя весь связанный код вместе, вместо того, чтобы иметь дополнительный, легко забываемый фрагмент кода в верхней части функции.Лично я склонен объявлять как
var
первое присвоение переменной в независимом разделе кода, независимо от того, есть ли другое отдельное использование того же имени переменной в некоторой другой части той же функции. Для меня необходимость объявленияvar
вообще является нежелательной бородавкой JS (было бы лучше иметь переменные по умолчанию локальные); Я не считаю своим долгом дублировать ограничения [старой редакции] ANSI C в JavaScript.(*: кроме как во вложенных функциональных телах)
источник
var
которое используется только в верхней части функции - это просто запрос на случайное создание глобальной переменной. И иметь массу несвязанных переменных, объявленных в одном месте, семантически бессмысленно, особенно когда некоторые из этих переменных могут в итоге никогда не использоваться.В теории это не должно иметь никакого значения в JavaScript, так как язык не имеет области видимости блока, а только области действия функции.
Я не уверен насчет аргумента производительности, но Дуглас Крокфорд по- прежнему рекомендует, чтобы эти
var
операторы были первыми в теле функции. Цитирование из условных обозначений кода для языка программирования JavaScript :Я думаю, что у него есть точка, как вы можете видеть в следующем примере. Объявление переменных в верхней части функции не должно вводить читателей в заблуждение о том, что переменная
i
содержится в областиfor
блока цикла:источник
ecma- / javascript
увеличит их во время выполнения. Это называется «Подъем». Так что не должно быть никакой разницы.let
влияет на этот ответ?ECMA-/Javascript
Языкhoists
любой переменной , которая объявлена в любом месте в верхней части функции. Это происходит потому , что этот язык действительно естьfunction scope
и не не имеют ,block scope
как и многие другие C-подобных языков.Это также известно как
lexical scope
.Если вы объявите что-то вроде
Это получается
hoisted
:Так что это не имеет никакого значения в производительности (но поправьте меня, если я совершенно не прав).
Гораздо лучшим аргументом для того, чтобы не объявлять переменную где-то еще, кроме как в верхней части функции, является удобочитаемость . Объявление переменной внутри оператора
for-loop
может привести к неверному предположению, что эта переменная может быть доступна только в теле цикла, что совершенно неверно . Infact вы можете получить доступ к этой переменной в любом месте в текущей области.источник
let
влияет на этот ответ?В следующем году все браузеры будут иметь движки JS, которые прекомпилируют код, поэтому разница в производительности (которая возникает из-за повторного анализа одного и того же блока кода плюс выполнение назначения) должна стать незначительной.
Кроме того, никогда не оптимизируйте для производительности, если вам не нужно. Держите переменные рядом с тем местом, где они вам нужны в первый раз, чтобы ваш код был чистым. С другой стороны, люди, привыкшие к языкам с блочными областями, могут быть сбиты с толку.
источник
Еще одно соображение, которое мы имеем
let
иconst
в ES2015, заключается в том, что теперь вы можете привязывать переменные конкретно к блоку цикла. Поэтому, если вам не понадобится одна и та же переменная вне цикла (или если каждая итерация зависит от операции, выполненной с этой переменной на предыдущей итерации), вероятно, предпочтительнее сделать это:источник
Я только что сделал простой тест в Chrome. Попробуйте скрипку в вашем браузере и посмотрите результаты
В результате последний тест занимает ~ 8 секунд, а предыдущие 2 - всего ~ 2 секунды. Очень многократно и независимо от порядка.
Итак, это доказывает мне, что всегда следует объявлять переменные вне цикла. Любопытный случай для меня - это первый случай, когда я объявляю
i
в операторе for (). Похоже, что этот тест выполняется так же быстро, как и второй тест, в котором я предварительно объявляю индекс.источник
var
объявляет как глобальную переменную, которая будет быть глобальным в любом случае.JavaScript - это язык, написанный внизу на C или C ++, я не очень уверен, какой это. И одной из его целей является сохранение большого объема работы с внутренней памятью. Даже в C или C ++ вам не придется беспокоиться о том, будет ли он потреблять много ресурсов, когда переменные объявляются внутри цикла. Почему вы должны беспокоиться об этом в JavaScript?
источник
Ну, это зависит от того, чего вы пытаетесь достичь ... если
value
предположить, что в блоке цикла есть только временная переменная, тогда гораздо понятнее использовать вторую форму. Это также более логично и многословно.источник
Не имеет значения, если вы объявляете переменные внутри или снаружи цикла for. Ниже приведен пример кода для тестирования.
Результаты показали в моем случае
Спасибо - MyFavs.in
источник
let
вместоvar
и,a()
как правило, немного медленнее (например, 120 против 115 мс = ~ 6% = IMO незначительно)Вопрос здесь заключается в том, чтобы объявить переменную внутри цикла. Подумайте, что произойдет, если вы сделаете это:
Как вы думаете, это правильно? Нет ... потому что вы не хотите объявлять переменную столько раз. Когда вы объявляете переменную внутри цикла, разве она не объявляется столько раз, сколько выполняется цикл? Очевидно, это даст вам пощечину, когда вы находитесь в режиме «использования строгого режима». Люди не согласны с Крокфордом, не задумываясь о первоначальном вопросе.
Так что всегда хорошо объявлять переменные сверху - 1. Для удобства чтения, 2. Создание хороших привычек.
источник
Что касается производительности после запуска тестирования в Chrome, Firefox и jsperf в ОС Linux, то существует разница в производительности между объявлением переменных в цикле и вне цикла. Это небольшая разница, но она также осложняется количеством итераций и количеством объявлений переменных.
Поэтому для лучшей производительности я должен был бы предложить объявить переменные вне цикла. Или еще лучше объявить ваши переменные в строке. Смотрите пример.
Обратите внимание, как переменные 'al' и 'av' находятся в строке объявления цикла for. Эта встроенная декларация обеспечила мне неизменно лучшую производительность. Даже за объявлением переменных вне цикла. Опять же разница в производительности очень мала.
https://jsperf.com/outside-inline-for-loop-ase/1
источник