Javascript预编译
ref:http://hi.baidu.com/do_itdream/item/3d75af3c9ec7cf667c034bbc
Javascript预编译
今天看了一位高人的一篇文章,把javascript讲得很是透彻,就像是在念诗一样,可见其境界之高。
现摘抄部分经典的,分享给自己和大家。
什么是JavaScript的“预编译”?
看下面的例子:
function myfunc ()
{
alert("hello");
};
myfunc(); //这里调用myfunc,输出yeah而不是hello
function myfunc ()
{
alert("yeah");
};
myfunc(); //这里调用myfunc,当然输出yeah
按理说,两个签名完全相同的函数,在其他编程语言中应该是非法的。但在JavaScript中,这没错。不过,程序运行之后却发现一个奇怪的现象:两次调用都只是最后那个函数里输出的值!显然第一个函数没有起到任何作用。这又是为什么呢?
原来,JavaScript执行引擎并非一行一行地分析和执行程序,而是一段一段地进行预编译后让后 再执行的。而且,在同一段程序中,函数 在被执行之前 会被预定义,后定定义的 同名函数 会覆盖 先定义的函数。在调用函数的时候,只会调用后一个预定义的函数(因为后一个预定义的函数把前一个预定义的函数覆盖了)。也就是说,在第一次调用myfunc之前,第一个函数语句定义的代码逻辑,已被第二个函数定义语句覆盖了。所以,两次都调用都是执行最后一个函数逻辑了。
如果把这个JavaScript代码分成两段,例如将它们写在一个html中,并用<script/>标签将其分成这样的两块:
<script>
function myfunc ()
{
alert("hello");
};
myfunc(); //这里调用myfunc,输出hello
</script>
<script>
function myfunc ()
{
alert("yeah");
};
myfunc(); //这里调用myfunc,输出yeah
</script>
这时,输出才是各自按顺序来的,也证明了JavaScript的确是一段段地执行的。
一段代码中的定义式函数语句会优先执行,这似乎有点象静态语言的编译概念。所以,这一特征也被有些人称为:JavaScript的“预编译”。
再来看一个例子:
if(!a ){//该语句会报错,说a没有定义 a=1; alert("傻瓜1号"); }
但是如果这样就不会报错,你知道为什吗??
if(!a ){ var a; var a=1; if(!a){ alert("大傻瓜"); 相当于 a=1; } // alert("大傻瓜");
}
alert(a);//undefined,a只是进行预定义了,并没有进行赋值,所以是undefined
if(!a ){ //判断a 有没有声明,如果有则执行下面语句 var a=1; alert("大傻瓜"); } //
因为JS 在执行前会进行类似"预编译"的操作,而且先预定义变量再预定义函数。预定义变量只是声明了一下变量,而并没有对其赋值。