Почему локальная переменная убивает мою глобальную переменную? - PullRequest
25 голосов
/ 31 марта 2011

Извините за этот вопрос, но эта проблема действительно испортила мой день.

Следующий код предупреждает 10 как следует:

var globalId='10';  
function check(){  
    alert(globalId);  
}  
check();

Но это следующеепредупреждения о коде undefined :

var globalId='10';  
function check(){  
    alert(globalId); 
    var globalId; 
}  
check();

Мне известно, что если я объявил переменную в функции как локальную переменную, но если я уже объявил ее как глобальную, как это может бытьВ моих предупреждениях указано: undefined ?

Это простой пример, но в моем исходном коде я много чего делал между началом функции, а затем прошел долгий путь вниз, чтобы проверитьпосмотрите, был ли определен globalId, иначе определите его: if(!globalId){var globalId;} Это означало, что мое оповещение, расположенное в верхней части функции, генерировало неопределенное, как будто JavaScript сначала выполнил всю функцию, просто чтобы увидеть, могут ли быть объявлены какие-либо переменные.и, если да, объявите их, и поэтому мое предупреждение указывало на необъявленную переменную.

Может кто-нибудь объяснить мне, почему это происходит, и если это правда, что JavaScript «предварительно объявляет» все переменные передпри выполнении функции, даже если переменные объявлены в условиях, которые даже не выполняются?

Ответы [ 6 ]

23 голосов
/ 31 марта 2011

В javascript вы должны знать, что есть нечто, называемое HOISTING .

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

Например: -

var globalId='10';
function check(){
alert(globalId); var globalId; }
check(); 

Меняется на -

var globalId='10';
function check(){
var globalId;
alert(globalId);}
check(); 

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

16 голосов
/ 31 марта 2011

Да, все переменные, объявленные в любом месте функции, являются локальными для этой функции и существуют во всем коде функции; они будут использоваться вместо глобалов с одинаковыми именами.

С https://developer.mozilla.org/en/JavaScript/Guide/Values,_Variables,_and_Literals#Variable_Scope:

JavaScript не имеет области действия оператора блока; скорее он будет локальным по отношению к коду, в котором находится блок. [...] Еще одна необычная вещь в переменных в JavaScript - это то, что вы можете ссылаться на переменную, объявленную позже, без получения исключения. Эта концепция известна как подъем; переменные в JavaScript в некотором смысле «подняты» или подняты в верхнюю часть функции или оператора.

13 голосов
/ 31 марта 2011

Во второй части кода локальная переменная маскирует глобальную.

var globalId='10';

function check() {
    // Your are defining a local variable in this function
    // so, the global one is not visible.
    alert(globalId);
    var globalId;
}

check(); 


Тот факт, что оператор yopur var находится в конце определения функции, ничего не меняет: глобальная переменная маскируется для всей функции .

Таким образом, для всего выполнения функции переменная globalId будет ссылаться на локальную, а не на глобальную.

Однако вне этой функции глобальная переменная все еще будет существовать - она ​​просто не будет видна внутри функции из-за оператора var.

4 голосов
/ 31 марта 2011

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

var globalId='10';

function check() {
    // Your are defining a local variable in this function
    // so, the global one is not visible.
    alert('Local : ' + globalId + ', Global : ' + window.globalId);
    var globalId;
}

check(); 
0 голосов
/ 31 марта 2011

, как будто Javascript впервые выполнил всю функцию, просто чтобы увидеть, могут ли быть объявлены какие-либо переменные

это ответ, более или менее. Интерпретатор JavaScript ищет объявления переменных в каждой области, а затем «перемещает их» в верхнюю часть области.

0 голосов
/ 31 марта 2011

вы объявляете НОВУЮ переменную globalId внутри области действия функции, поэтому она не определена, и это правильно.И нет, это не убивает вашу глобальную переменную, вы можете проверить это, добавив alert(globalId); после check(); вызова.

...