重新声明JavaScript变量有什么目的吗?

时间:2009-12-08 01:28:59

标签: javascript variables redeclaration

我是JavaScript的新手。

<html>
<body>
<script type="text/javascript">
var x=5;
document.write(x);
document.write("<br />");
var x;
document.write(x);
</script>
</body>
</html>

结果是:

5
5

第二次声明x时,它应该是未定义的,但它会保留先前的值。请解释这种重新声明是否有任何特殊目的。

9 个答案:

答案 0 :(得分:20)

你并没有真正重新声明变量。

JavaScript中的变量语句需要提升,这意味着它们将在分析时进行评估,稍后在运行时中进行分配。

您的代码在解析阶段结束时,在执行之前看起来像这样:

var x;
x = 5;

document.write(x);
document.write("<br />");
document.write(x);

答案 1 :(得分:7)

var不执行任务。它只标记当你在var发生的范围内使用变量名时,你所说的是局部变量而不是全局变量(有争议的默认值)。在解析函数时会发现var并在整个范围内保留,所以你把它放在哪里是无关紧要的:

var a= 0;

function foo() {
    a= 1;
    return a;
    var a;
}

var b= foo();
alert('global a='+a+', local a='+b);

global a= 0, local a= 1中的结果:即使在var的执行过程中从未达到foo()语句,它仍然可以使a成为局部变量。

因此,在同一范围内再次声明var x是完全多余的。但是,有时您可能仍会这样做,通常是在同一函数中重复使用局部变量名进行第二次独立使用时。最常见的是:

for (var i= 0; i<onething.length; i++) {
    ...do some trivial loop...
}

for (var i= 0; i<anotherthing.length; i++) {
    ...do another trivial loop...
}

虽然您当然可以省略第二个var,而像jslint这样的工具会要求您这样做,但实际上这可能并不是一个好主意。

想象一下,您稍后更改或删除第一个循环,以便它不再将i声明为var。现在剩下的第二个循环突然改变了从局部变量到全局变量的含义。如果您在更新第一个循环时没有注意到第二个循环对它有隐藏的依赖关系(并且您很可能没有注意到眼睛如何将模式for(...=0 ; ...<...; ...++)忽略为“哦,那只是一个标准iterator“),你有一个微妙而烦人的调试问题。

答案 2 :(得分:1)

  

所以当第二次声明x时应该是未定义的

规范的哪一部分说明了这一点?

“未定义的行为”并不意味着“变量将是undefined”。

答案 3 :(得分:0)

就我对javascript的理解而言,使用var关键字在全局范围中是完全可选的。这是功能的另一个故事。

在函数内部时,使用var关键字指示变量是函数的本地变量(而不是默认情况下是全局变量)。

我个人在全局范围内使用var来表明变量是第一次被声明和/或使用。

您可以参考http://www.w3schools.com/js/js_variables.asp了解更多信息。

答案 4 :(得分:0)

第二个var x完全是多余的。

答案 5 :(得分:0)

相同范围内,完全没必要“重新声明”变量。

答案 6 :(得分:0)

此外,程序员可能希望使用var来本地化变量:

<script>
var x= 'this is global x';
function my_x() {
 var x= 'localized x';
 alert(x);
}
my_x();
alert(x);
</script>

答案 7 :(得分:0)

如果你真的想要更改它然后分配给它,你应该从不重新声明同一范围内的变量。如果您希望x只是一个字符串,则不需要重新声明在此动态语言中创建不同的对象:

x = "hello";

您不需要先将其设置为未定义或重新声明。

请注意,在大多数情况下,更改变量类型并不是一个很好的做法,只是声明如果这是你需要的可能性。

答案 8 :(得分:0)

我最近编写的代码如下:

var obj1 = get_an_object();
var v = obj1.get_velocity();
v += changes_in_velocity();
obj1.set_velocity(v);

var obj2 = get_an_object();
var v = obj2.get_velocity();
v += changes_in_velocity();
obj2.set_velocity(v);

(实际代码更复杂,重复性更低)

就浏览器而言,第二个var v语句是多余的,毫无意义。对我来说,它有两个目的。它说要忘记我对旧v所知道的一切,因为这是一个新用法。这意味着我可以重新订购代码,或者在不破坏事情的情况下评论上半部分。