javascript 的預解析:(個人理解)代碼在執(zhí)行之前 會在相應的執(zhí)行環(huán)境中預先把 一些東西解析到內(nèi)存
**一. 那究竟預先解析哪些東西那??答:預先解析 function 和 var
**二. 還有就是預解析的順序是怎們樣的?
1首先是找到<script></script>標簽按照<script>塊依次解析
2 解析執(zhí)行環(huán)境(這個有點難理解,在下面有具體解釋)
3 對標識符( var function)進行解析 (http://blog.csdn.net/u014205965/article/details/45620607#) copy
<script>
test(); // This is test
function test()
{
alert('This is test');
}
</script>
以上案例,在function test()之前就調(diào)用了test()函數(shù)照樣可以彈出 This is test
可見在js執(zhí)行之前就預先把function test解析到了內(nèi)存,所以調(diào)用test() 照常彈出結(jié)果;
接下來看看變量的預解析:
[javascript] view plain copy
<script>
alert(test);//undefined
var test="this is test";
alert(test);//this is test
</script>
在var test=“test”,之前就調(diào)用alert彈出test,而沒有 報test未定義的錯誤,而是彈出了undefined,可見在js執(zhí)行之前就預先把var test;解析到內(nèi)存,所以不會報錯,為什么會彈出undefined是因為,只是把var test的定義預先解析到內(nèi)存,并沒有給變量賦值;
[javascript] view plain copy
var test="this is test";
當我們執(zhí)行完這句話的時候,就完成了賦值,所以再次調(diào)用alert就彈出this is test
接下來繼續(xù)看:變量和函數(shù)重名的時候會是什么情況?
[javascript] view plain copy
<script>
alert(test); //function(){ return " this is function"}
var test="this is test";
function test(){
return "this is function";
}
alert(test); // this is test
alert(test()); // this is function
</script>
這段代碼證明了,當函數(shù)名和變量名一樣的時候,alert(test);調(diào)用的是函數(shù)function test() 的指針,而不是調(diào)用的變量var test; 所以function的預解析 優(yōu)先級 高于var(個人覺得)
接下來說說“ 解析執(zhí)行環(huán)境 ”是什么意思??看下面的例子
[javascript] view plain copy
<script>
function test(){
var msg ='This is test';
}
alert(msg); // 報錯msg未定義
</script>
可能有人會有疑問了,按照上面說的js不是會預解析function 和 var msg嗎,我在function 里面定義了var msg ,那為什么調(diào)用回報錯那???
答案就和我們上面提到的 “解析執(zhí)行環(huán)境” 有關(guān)系,在js執(zhí)行之前是會預解析function 和var 沒錯,但是在本例中 他們“解析執(zhí)行環(huán)境”不同.
Function test是在一個全局的環(huán)境中,而msg是function test中定義的一個局部變量,msg的“解析執(zhí)行環(huán)境”是在function test這個函數(shù)里面(這里可以理解為function test里的局部環(huán)境),所以當我們在全局這個環(huán)境中alert(msg),的時候,并沒有定義msg這個變量或者函數(shù),所以就報錯了;
為了進一步理解,把上面的例子加以修改
[javascript] view plain copy
<script>
alert(msg); // undefined
function test()
{
alert(msg2);//undefined
var msg2 ='This is test';
}
var msg = "123";
test();
</script>
這個例子,js在執(zhí)行之前預解析,解析全局的環(huán)境,解析到function test 和 var msg ;所以alert(msg);會彈出undefined;
然后當程序執(zhí)行到test(); 的時候會進入function test里面去,也就是進入function test 的局部環(huán)境去 預解析,這時候解析到 var msg2,所以也彈出了undefined;
為了理解的更清楚,可以用IE的F12打個斷點看一下
程序開始預解析的時候,實在Global這個全局的執(zhí)行環(huán)境中,解析到了function test 和msg
當我們執(zhí)行test()的時候,就會進入function test里面這個局部執(zhí)行環(huán)境去解析了
上圖可以看到黃色的箭頭 有原來的Global 執(zhí)行環(huán)境,變成了test則個局部執(zhí)行環(huán)境了,然后再function test這個局部執(zhí)行環(huán)境中預解析,此時就解析到了 var msg2 這個變量
到這應該可以理解“解析執(zhí)行環(huán)境”這句話了吧,如果還不明白自己動手搞了例子,打個斷點debug一下下面這段代碼,應該就清楚了!
[javascript] view plain copy
<script>
var a = "我是全局的a";
var b = " 我是全部的b";
function fun1(){
var a = "我是局部的a";
alert(a);
function fun2(){
alert(a);
alert(b);
}
func2();
}
fun1();
</script>
最后說明一下“1首先是找到<script></script>標簽按照<script>塊依次解析” 這句話是什么意思那?
我們的代碼中可能會有多個<script>...</script>標簽,每一個<script>...</script>標簽我們認為是一個<script>塊;js的預解析式按照<script>塊來進行的;也就是說js預解析不會跨<script>塊去進行預解析,什么意思那?看下面代碼
[javascript] view plain copy
<script>
alert(msg);
//test();
</script>
<script>
var msg ="test";
/* function test(){
alert("this is function");
}*/
</script>
這里有兩個script塊,他們是按照順序進行預解析的,我們在第二個script塊中定義的var msg,而在第一個script塊中alert(msg)
顯然在第一個script快中并沒有預解析到一個叫msg的變量或者函數(shù),而js又不會跨到第二個script塊去解析,所以就報錯msg未定義
函數(shù)function test 也一樣
如果把兩個script塊調(diào)換一下位置,結(jié)果就不一樣了
[javascript] view plain copy
<script>
var msg ="test";
function test(){
alert("this is function");
}
</script>
<script>
alert(msg); // test
test(); // this is function
</script>
script塊順序進行預解析,當?shù)谝粋€script塊預解析完,會解析到var msg 和function test,
當再第二個script塊中調(diào)用alert(msg);和test();時上面的js程序已經(jīng)執(zhí)行完畢了,自然會彈出 test 和this is function