Объявленная Javascript глобальная переменная переопределяет старое значение - PullRequest
1 голос
/ 14 апреля 2010

Я столкнулся с интересной проблемой на днях и задавался вопросом, может ли кто-то пролить свет на то, почему это происходит. Вот что я делаю (для целей этого примера я немного озвучил пример):

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

Ответы [ 4 ]

1 голос
/ 14 апреля 2010

? Я только что проверил ваш код, и он показывает «старый», и я проверил FF, Chrome, Safari (ПК) и IE8.

Смотрите здесь: http://jsbin.com/ifare/edit

1 голос
/ 14 апреля 2010

Оператор 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 вы видите реальное поведение кода.

Смотри также:

0 голосов
/ 14 апреля 2010

Вы не можете «повторно объявить» переменные в той же области видимости в 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
}

потому что не существует такой вещи, как область действия "блока".

0 голосов
/ 14 апреля 2010

Когда вы повторно объявили y с помощью var y;, теперь оно не определено, поэтому 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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...