Есть ли недостатки в использовании var более одного раза в одной переменной в JavaScript?

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

Мне просто интересно, есть ли функциональная, память или производительность для использования объявления переменной в одной и той же переменной более одного раза внутри функции.

Вот пример:

function foo() {
  var i = 0;
  while (i++ < 10) {
    var j = i * i;
  }
}

Предыдущее может быть просто записано с помощью объявленного выше j variabled:

function foo() {
  var i = 0, j;
  while (i++ < 10) {
    j = i * i;
  }
}

Мне интересно, существует ли какая-либо фактическая разница между этими двумя методами. Другими словами, делает ли ключевое слово var чем-либо иным, чем устанавливать область видимости?

Причины, по которым я слышал, предпочитаю второй метод:

  • Первый метод дает видимость области блока, когда она фактически функция область.
  • Переменные объявления поднимаются до верхней части области действия, так что там, где они должны быть определены.

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

Ответ 1

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

Как вы уже знаете, любое объявление переменной будет поднято в верхней части функции. Важно отметить, что это происходит во время процесса интерпретации/компиляции, а не во время выполнения.

Перед выполнением функции необходимо проанализировать функцию. После того как каждая функция будет разобрана, они оба будут иметь все объявления переменных, перемещенные в верхнюю часть, что означает, что они будут идентичными и не будет произведено никаких затрат времени на выполнение.

По той же причине нет различий в стоимости памяти. После разбора не будет различий вообще.


Поскольку вы не спрашиваете о стиле, я не говорю вам, что я думаю лучше. Но я скажу, что единственная причина, по которой вы должны отдать предпочтение друг другу, - это стиль.

Ответ 2

Стиль

Субъективная. Я предпочитаю подход, который поддерживает var близко к сайту использования, но я всегда соблюдаю правила обзора. Я также избегаю объединения нескольких объявлений в один var и предпочитаю несколько операторов var.

Выделение памяти

Переменные не являются объектами: неприменимы. Из-за правил подъема переменный "слот" имеет одинаковое время жизни во всех случаях.

Производительность

Нет. Не должно быть разницы в показателях производительности. Хотя реализация может технически реально испортить это - они этого не делают.

Единственный способ ответить на этот вопрос (помимо поиска в каждой реализации в minutia) - использовать контрольный показатель.

Результат: разница шума в современных браузерах

Ответ 3

В JavaScript - Хорошие детали Дуглас Крокфорд предполагает, что, используя второй метод и объявляя ваши переменные в верхней части своей области, вы будете больше легко избежать ошибок области.

Они часто вызывают циклы for, и их очень сложно отследить, поскольку ошибки не будут возникать. Например:

function() {
  for ( var i = 0; i < 10; i++ ) {
    // do something 10 times
    for ( var i = 0; i < 5; i++ ) {
      // do something 5 times
    }
  }
}

Когда переменные будут подняты, мы получим только один i. И, таким образом, второй цикл перезаписывает значение, предоставляя нам бесконечный цикл.

Вы также можете получить некоторые причудливые результаты при работе с функцией подъема. Возьмите этот пример:

(function() {
  var condition = true;
  if(condition) {
    function f() { console.log('A'); };
  } else {
    function f() { console.log('B'); };
  }
  f(); // will print 'B'
})();

Это потому, что тела функций подняты, а вторая функция перезаписывает первый.

Поскольку поиск таких ошибок сложный и независимо от каких-либо проблем с производительностью (я редко обожаю пару микросекунд), я всегда объявляю свои переменные в верхней части области.

Ответ 4

Ваш пример будет работать точно так же. Однако может быть еще более неясным, чем ваш пример использовать "var" в блоке. Скажем, например, вы хотите обновить переменную, которая находится за пределами области действия (не используя "var" ), или вместо этого использовать локальный "var". Даже если это условие ложно, "j" становится локальным. Оказывается, это не так просто, как кажется.

var j = 1;
function foo () {
    j = 2;
    if (false) {
        var j = 3; // makes `j = 2` local simply for being in the same function
    }
    console.log(j);
}
foo(); // outputs 2
console.log(j); // outputs 1

Этот сложный случай, который может не работать так, как вы ожидаете, просто просмотрев код.

Нет недостатков в объявлении каждого "var" сверху, только вверх.

Ответ 5

Второй способ сохраняет 4 символа в файле javascript, но с точки зрения фактической генерации кода или скорости выполнения я не считаю, что есть какая-то разница.