Javascript redeclared global variable переопределяет старое значение
На днях я столкнулся с интересной проблемой и задавался вопросом, может ли кто-нибудь пролить свет на то, почему это происходит. Вот что я делаю (для целей этого примера я немного пошатнул пример):
- Я создаю глобальную область с переменной квадратной скобкой и присваиваю ей значение.
-
Позже я объявляю var с тем же именем, что и тот, который я только что создал. Примечание. Я не назначаю значение. Поскольку это переопределение одной и той же переменной, старое значение не должно переоцениваться, как описано здесь: http://www.w3schools.com/js/js_variables.asp
//create global variable with square bracket notation
window['y'] = 'old';
//redeclaration of the same variable
var y;
if (!y) y = 'new';
alert(y); //shows New instead of Old
-
Проблема состоит в том, что старое значение действительно перегружается и в приведенном выше примере. предупреждение показывает "новое" вместо "старого". Почему?
Я предполагаю, что другой способ сформулировать мой вопрос заключается в том, как приведенный выше код отличается семантикой из приведенного ниже кода:
//create global variable
var y = 'old';
//redeclaration of the same variable
var y;
if (!y) y = 'new';
alert(y); //shows Old
Обновление 1. Основываясь на некоторых комментариях и ответах, я перефразирую этот пример, чтобы лучше отразить мою оригинальную проблему.
Создайте 2 файла javascript со следующим содержимым:
Script1
//create global variable with square bracket notation
window['y'] = 'old';
Скрипт2
//redeclaration of the same variable
var y;
if (!y) y = 'new';
alert(y); //shows New instead of Old in IE
Включите эти 2 файла в свой html файл
<html>
<head></head>
<body>
<script type="text/javascript" src="my.js"></script>
<script type="text/javascript" src="my2.js"></script>
</body>
</html>
Открытие этой страницы в Firefox и Chrome предупреждает "старый", что является ожидаемым поведением. Однако в IE 8 страница будет на самом деле предупреждать "новый"
Обновить 2 вопрос: Измененная глобальная переменная javascript переопределяет старое значение в IE
Ответы
Ответ 1
Операция var
подвержена подъему, это означает, что когда код входит в контекст выполнения (непосредственно перед фактической средой выполнения), операторы var
и function
становятся доступными для своей охватывающей области.
В действительности ваш код оценивается следующим образом:
Первый пример:
var y;
window['y'] = 'old';
if (!y) y = 'new';
alert(y);
Второй пример:
var y;
y = 'old';
if (!y) y = 'new';
alert(y);
Когда оператор var
поднят, вы увидите фактическое поведение, которое имеет код.
См. также:
Ответ 2
? Я просто проверил ваш код, и он показывает "старый", и я тестировал FF, Chrome, Safari (ПК) и IE8.
Посмотрите здесь: http://jsbin.com/ifare/edit
Ответ 3
Когда вы обновили y
с помощью var y;
, теперь он undefined, поэтому if(!undefined)
получает значение true.
Добавьте еще одно предупреждение в свой пример, чтобы увидеть это:
//create global variable with square bracket notation
window['y'] = 'old';
//redeclaration of the same variable
var y;
alert(y); //undefined
if (!y) y = 'new';
alert(y); // new
var
не будет инициализировать переменную дважды, но она перезапишет одну, не инициализированную в первый раз (потому что это новая, более локальная переменная), которую делает стиль window['y']
, добавляя его к объекту окна. Возьмите это, например:
//create global variable with square bracket notation
window['y'] = 'old';
//redeclaration of the same variable
var y;
alert(y); //undefined
alert(window.y); //old
if (!y) y = 'new';
alert(y); //shows New instead of Old
alert(window.y); //still old
Ответ 4
Вы не можете "переопределять" переменные как таковые в пределах той же области действия в JS.
var x = "foo"
function a()
{
alert(x); // undefined
var x;
}
В функции a
переменная x
является локальной, поскольку она имеет var x
. Не имеет значения, идет ли оно до или после использования.
Аналогично:
function b()
{
var z = 1;
if (true)
{
var z = 2;
}
alert(z); // 2
}
потому что не существует такой области, как область "block".