JS之預解析

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

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內(nèi)容

  • 工廠模式類似于現(xiàn)實生活中的工廠可以產(chǎn)生大量相似的商品,去做同樣的事情,實現(xiàn)同樣的效果;這時候需要使用工廠模式。簡單...
    舟漁行舟閱讀 7,827評論 2 17
  • 第一章: JS簡介 從當初簡單的語言,變成了現(xiàn)在能夠處理復雜計算和交互,擁有閉包、匿名函數(shù), 甚至元編程等...
    LaBaby_閱讀 1,697評論 0 6
  • JavaScript是解釋性語言,運行的時候動態(tài)解析執(zhí)行 JavaScript加載編譯的時候,是以 遵守docum...
    _未名閱讀 340評論 0 1
  • 單例模式 適用場景:可能會在場景中使用到對象,但只有一個實例,加載時并不主動創(chuàng)建,需要時才創(chuàng)建 最常見的單例模式,...
    Obeing閱讀 2,093評論 1 10
  • 這是潘藍一寫的第16篇潘寶貝原創(chuàng)文章 微信:beibaopan 微信公眾號:...
    潘藍一閱讀 553評論 0 0