#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 Отличное замечание. Поскольку я всегда создаю новую пустую вкладку, я забываю об этом. То, как мы тестируем, так же важно, как и то, что мы тестируем.