所谓语言都是相通的,这里说的语言,是指程序语言,而不是国家之间的交流语言。就像java有编译阶段和执行阶段一样,JavaScript也有两个阶段,即预处理阶段和执行阶段。那么这两个阶段都干了些什么事呢,且听我罗里吧嗦的为你一一道来。
预处理阶段,即变量定义阶段,在这个阶段,它会把所有已经声明的变量放到一个对象中,这个对象等同于window对象,但又不是window对象。但是,要注意一点,这里所说的声明变量,是指以var 声明的变量或者声明方式创建的函数对象。
1 2 3 4 5 6 7 8 9 10 11 12 13 |
alert(a); alert(b); alert(c); var a = 5; //这是var声明的function,为函数表达式 var b = function(){ console.log("b"); } //这是声明式创建的函数对象 function c(){ console.log("c"); } |
以上这段代码,也许你会认为都会报错,因为在alert之前未定义,直接是not defined,其实不然,前两个alert的结果均为undefind,第三个为function c的方法体。为什么?这就是上面所说的js有预处理阶段,它会把以var 声明的变量放到一个对象中,并给一个初始值undefind,而这个对象等同于window对象。意思就是像下面这样。
1 2 3 4 5 6 7 |
window{ a:undefined, b:undefined, c:function (){ console.log("c"); } } |
这里c有所不同,因为它是声明式创建的,预处理阶段就知道它的值了。而a和b是通过var创建的,只有在运行的时候才会被赋值。换成下面这样,就是你想要的结果了。
1 2 3 4 5 6 7 8 9 10 11 12 13 |
var a = 5; //这是var声明的function,为函数表达式 var b = function(){ console.log("b"); } //这是声明式创建的函数对象 function c(){ console.log("c"); } alert(a); alert(b); alert(c); |
因为在alert之前上面的已经运行了。自然就有值了。
但如果一个变量像b=5这样定义,在预处理阶段不会对它做任何处理,而是在运行阶段一并解决。
1 2 3 |
console.log(b);//报错,not defined b = 5; console.log(b);//5,因为运行到b=5时b被创建且马上赋值 |
在编写代码时,建议不要像b=5这样写,因为没有用var声明的变量,都为全局变量,属于window对象。如:
1 2 3 4 5 |
function h(){ b = 5; } h(); alert (window.b);//5 |
但如果在b前面加了var ,结果则是undefined。
发表评论