1. 变量定义和初始化顺序
Javascript 是一种解释型语言,在脚本加载时,解释器会扫描所有变量定义语句并定义这个变量,但是不会给初始值,即使定义语句里已有赋值操作;而是当程序运行到该语句时,才会按定义给定初值。即是说,在变量作用域内,在变量定义语句之前该变量的值为undefined。
<script language="JavaScript">
<!--
function test() {
alert(t); //alert undefined
var t = 1;
}
test();
//-->
</script>
上边的脚本会弹出undefined,这说明变量t已存在,只是他的值还没被定义。如果注释掉ver t = 1这一句,程序会报脚本错误:变量t未定义。这也印证了这一特性。
2. 全局变量
Javascript中定义一个变量,var关键字不是必须的。如果不使用var关键字,那么,第一次给变量赋值就会定义这个变量。不过需要注意的是,这样定义的变量,该语句不论在什么位置(即使在函数中)都会定义成全局变量。因此,全局变量有两种方式:一是在全局范围内使用var定义,一是在任意位置不使用var定义变量。
<script language="JavaScript">
<!--
var g = "全局变量";
function test1() {
g1 = "函数中定义的全局变量";
}
//alert(g1); // error: g1 is undefined
test1();
alert(g1);
//-->
</script>
通过上边的脚本可以看出,g1被定义为了全局变量,第一次alert(g1)之所以会报错而不是弹出undefined,是因为解释器只会预定义那些有var的定义语句,如果注释掉test1()这一句,那接下来的alert(g1)也会报同样的错误。
3. 全局变量和局部变量
Javascript 在变量的作用域定义上是比较奇怪的,像上边的例子你可以在函数中定义全局变量一样,我们同样可以在循环中定义一个局部变量供整个函数内部使用。而且,JS允许局部变量与全局变量重名,这样的局部变量只会在他的作用范围(比如函数)内起作用,而不会影响和它同名的全局变量。如下例。
<script language="JavaScript">
<!--
var g = "全局变量g";
function test2() {
while (true) {
var t = "循环中定义的变量";
break;
}
alert(g); // alert undefined
var g = "函数中定义的g";
alert(g); // alert 函数中定义的g
alert(t); // alert 循环中定义的变量
}
test2();
alert(g); // alert 全局变量g
//-->
</script>
但是如果在函数中存在变量的定义语句,即使定义语句在赋值语句只后,该变量也会被认为是局部变量。如下例,因为当执行t = "变量t"时,t已经被定义为一个局部变量了。
<script language="JavaScript">
<!--
function test3() {
t3 = "变量t3";
var t3;
}
test3();
alert(t3); // error: t is undefined
//-->
</script>