Происходит ненужный подъем.! почему?

#javascript

#javascript

Вопрос:

 function test() {
    a = 10;
    alert(a);
    if (false) {
        var a;
    }
}

test();
  

Из приведенного выше кода вы можете видеть, что я объявил одну переменную внутри ложного оператора if, что означает, что код внутри него не будет выполнен. Смотрите, теперь эта переменная поднята ненужно, почему это так ..? Это привело бы к излишнему выделению памяти. Разве компилятор недостаточно умен, чтобы идентифицировать это ..? Или эти переменные будут собраны в мусор, такой как java.?

Данный блок кода будет интерпретироваться как,

 function test() {    
    var a;
    a = 10;
    alert(a);
    if (false) {   
    }    
}

test();
  

Логически, какой смысл выводить переменную из ложного утверждения.? Если var a; выделяет какую-либо память внутри, то это не оптимизированная, верно ..?

Комментарии:

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

2. Что вы имеете в виду под «излишне выделять память»? Он использует один и тот же объем памяти независимо от того, поднят он или нет.

3. @RajaprabhuAravindasamy но любое var утверждение перемещается наверх. Всегда. Исключений нет. Не имеет значения, что вы вкладываете в это.

4. Условие if инструкции оценивается во время выполнения. «Изменение порядка» выполняется при разборе кода. Несмотря ни на что, var будет перемещен в верхнюю часть заключающей функции.

5. …в конечном счете, у вас нет детального контроля над памятью, который есть в C. Хорошо быть консервативным в использовании памяти в JS, но не на таком уровне. Пусть об этом позаботится движок JS.

Ответ №1:

В примере Mozilla больше говорится о подъеме переменных

Вы заметите, что

 function test() {
  a = 10;
  alert("Function a="   a);
  if (false) {
    var a;
  }
}

test();
alert("Global a="   a);
  

выдает ошибку not defined для a в «Глобальной» строке, на которую из-за ограничения области видимости вы не попадете

 function test() {
  a = 10;
  alert("Function a="   a);
}

test();
alert("Global a="   a);
  

Итак, из объяснения в документах ваш код равен:

 function test() {
  var a;
  a = 10;
  alert(a);
  if (false) {
  }
}

test();
  

поскольку объявление обрабатывается до выполнения любого другого кода.

Комментарии:

1. хороший ответ, за который проголосовали. Я бы просто добавил бит, когда вы говорите gives and error для чего-то вроде outputs undefined .

2. @bitoiu — на самом деле это не выводится undefined . Выдает ошибку: ReferenceError: a is not defined . Вы можете видеть это в консоли при запуске этого: jsfiddle.net/jfriend00/LHe8U . Это то, что происходит, если вы пытаетесь получить доступ к несуществующим глобальным переменным, если вы не квалифицируете их как, window.a что было бы undefined .

3. В спецификации сказано «Если IsUnresolvableReference(V), генерируйте исключение ReferenceError». Это то, что я получаю в Chrome, когда тестирую перед написанием ответа.

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

5. @cookiemonster Отличное замечание. Поскольку я всегда создаю новую пустую вкладку, я забываю об этом. То, как мы тестируем, так же важно, как и то, что мы тестируем.