我是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
时,它应该是未定义的,但它仍然保留之前的值。请说明这种重新声明是否有特殊目的。
我是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
时,它应该是未定义的,但它仍然保留之前的值。请说明这种重新声明是否有特殊目的。
你并没有真正地重新声明变量。
在JavaScript中,变量声明会受到提升的影响,这意味着它们会在解析时进行评估,然后在运行时进行赋值操作。
在解析阶段结束之前,你的代码大致如下:
var x;
x = 5;
document.write(x);
document.write("<br />");
document.write(x);
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
中的结果是:尽管在执行 foo()
的过程中从未到达 var
语句,但它仍然有效地使 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 ; ...<...; ...++)
,你很可能没有注意到这一点),那么你就会遇到一个微妙而令人烦恼的问题,需要进行调试。var
关键字是完全可选的。但对于函数来说则是另一回事。var
关键字来表示该变量仅限于该函数内部(而不是默认为全局变量)。var
来显示一个变量是否第一次被声明和/或使用。var
来本地化一个变量:<script>
var x= 'this is global x';
function my_x() {
var x= 'localized x';
alert(x);
}
my_x();
alert(x);
</script>
那个第二个变量x是完全多余的。
在同一作用域内,您绝对不应该重新声明一个变量。如果您真的想要更改它,那么请给它赋值。在这种动态语言中,不需要重新声明就可以创建一个不同的对象。如果您想让 x 成为一个字符串,只需赋值即可:
x = "hello";
你不需要将它设置回未定义或者重新声明。
请注意,在大多数情况下,改变变量类型并不是一个很好的实践方式,仅仅是在必要时提供这个可能性。
我最近写了这样的代码:
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
,因为这是一个新的用法。其次,它意味着我可以重新排列代码或注释掉前半部分而不会破坏程序。