1 function TestClass() {
 2     //定义一个全局变量
 3     val = 1;
 4     alert(val);
 5     alert(window.val);
 6     //我仅仅是添加了以下代码
 7     //var val = 10;
 8 }
 9 //调用TestClass函数
10 test = new TestClass();
11 alert(val);

第三行定义一个不带var的全局变量,既然是全局变量,那么这个变量就会变成window对象的一个属性,所以第5、10行都输出10,这没有异议。但是看如下代码:

 1 function TestClass() {
 2     //定义一个全局变量?
 3     val = 1;
 4     alert(val);
 5     alert(window.val);
 6     var val = 10;
 7 }
 8 //调用TestClass构造函数
 9 test = new TestClass();
10 alert(val);

第一个alert输出undefined,第二个报错,这是为什么呢?我就是仅仅加了一行 var val = 10; 这是因为:

其实javascript作为一个脚本语言也是有所谓的预编译的,所有以var声明的变量,var无论放在哪个部分都会放到作用域开头来定义,上面的效果其实等同于:

 

1 function TestClass() {
2     var val;
3     val = 1;
4     alert(val);
5     alert(window.val);
6     val = 10;
7 }

 

 这样一来,val就变成了一个局部变量。那为什么第一个会变成undefined,而第二个会语法报错呢?这是因为这两种写法还是有区别滴:第一种写法,window.val,这种写法,如果存在val属性,则取之;如果不存在则添加一个这样的属性,因为没有初始化,所以为undefined;第二种写法 alert(val); val没有声明就使用,这会报一个语法错误的。至此,已经解释清楚了。

 

其实javascript是没有块级作用域的,倒是有函数作用域,请看下面例子:

1 function t(){
2     for(var i = 0; i<4;i++){
3          
4     }
5     alert(i);
6 }
7 alert(i);

 

第一个alert可以输出4,第二个则报语法错误,证实了我上面的说法,具体可以参考《Javascript权威指南》。