Javascript重新声明的全局变量会覆盖旧值

时间:2010-04-14 02:01:45

标签: javascript global-variables scope

前几天我遇到了一个有趣的问题,并且想知道是否有人可以解释为什么会发生这种情况。这就是我正在做的事情(为了这个例子的目的,我在某种程度上贬低了这个例子):

  • 我正在使用方括号表示法创建一个全局范围的变量,并为其赋值。
  • 稍后我宣布一个与我刚才创建的名称相同的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';

SCRIPT2

//redeclaration of the same variable
var y;

if (!y) y = 'new';

alert(y); //shows New instead of Old in IE

在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 问题移至此处:Redeclared javascript global variable overrides old value in IE

4 个答案:

答案 0 :(得分:1)

var语句是提升的主题,这意味着当代码enters in execution context(在实际运行时之前)时,var和{{ 1}}语句可用于其封闭范围。

您的代码实际上会按以下方式进行评估:

第一个例子:

function

第二个例子:

var y;
window['y'] = 'old';

if (!y) y = 'new';

alert(y);

在提升var y; y = 'old'; if (!y) y = 'new'; alert(y); 语句后,您会看到代码所具有的实际行为。

另见:

答案 1 :(得分:1)

?我刚刚测试了你的代码并显示“旧”,我测试了FF,Chrome,Safari(PC)和IE8。

请看这里:http://jsbin.com/ifare/edit

答案 2 :(得分:0)

当您使用y重新声明var y;时,它现在未定义,因此if(!undefined)的计算结果为真。

Add another alert in your example to see this

//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

答案 3 :(得分:0)

你不能在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
}

因为没有“阻止”范围这样的东西。