輕松搞定javascript預解析機制(搞定后,一切有關變態面試題都是浮雲~~)


hey,guys!我們一起總結一下JS預解析吧!

首先,我們得搞清楚JS預解析JS逐行執行的關系。其實它們兩並不沖突,一個例子輕松理解它們的關系:

  你去酒店吃飯,吃飯前你得看下菜譜,點下菜(JS預解析),但吃的時候還是一口一口的吃(JS逐行執行)!

 

 

OK,解決下面五個問題,JS預解析就算過了~~(前提:對JS變量作用域有清晰理解)

一、JS預解析是什么?

其實就是對程序要用到的材料(變量,函數)給一個初始值,並存到一個表中(我自己虛構的),當程序運行到那一行時,就來這個表看有沒有初始值,沒有就報錯~~

 

二、JS在什么情況下會進行預解析呢?

1.遇到<script></script>標簽對時;

2.遇到函數時;(因為變量是有作用域的)

 

三、JS對什么進行預解析?

1.函數傳參的變量  

2.var 后面的變量

3.函數

 

四、那JS會給這些 變量、函數 賦予什么初始值呢?

1.凡是傳參,直接賦值參數;

2.凡是var 的,都會賦予一個 undefined 作為初始值;

3.凡是函數,直接賦予 函數本身 作為初始值;(所以這就是為什么我們可以把 函數調用 放到  函數聲明 之前的原因)

 

 

五、什么情況會改變 預解析 賦予的初始值呢? 

有賦值功能的符號:=,  +=,  -=,  *=,  /=,  ++,  --等 (如果還有再添加..)

 

下面是來點實例:

1 alert(a);    //報錯,沒有var 是不會進行預解析的
2 a = 0;
1 alert(a);    //undefined
2 var a = 0;
3 alert(a);    //0, =號 可以改變初始值
1 alert(a);    //function a(){ alert('我是函數') },  undefined代表空,函數不是空的,當然要不是空的啦!
2 var a = '我是變量';
3 function a(){ alert('我是函數') }
4 alert(a);    //'我是變量', = 可以改變初始值
1 alert(a);    //function a(){ alert('我是函數') },  undefined代表空,函數不是空的,當然要不是空的啦!
2 a++;
3 alert(a);    //NaN, ++可以改變初始值
4 var a = '我是變量';
5 function a(){ alert('我是函數') }
6 alert(a)    //'我是變量', = 可以改變初始值
 1 alert(a);    //undefined
 2 var a = 0;
 3 alert(a);    //0
 4 function fn(){
 5     alert(a);    //undefined;遇到函數,重新進行預解析
 6     var a = 2;
 7     alert(a);    //2
 8 }
 9 fn()
10 alert(a);    //0,fn里面的a與全局的a不是同一作用域的
 1 alert(a);    //undefined
 2 var a = 0;
 3 alert(a);    //0
 4 function fn(){
 5     alert(a);    //0;因為沒var, 所以這里的a會被看作是全局的,往上查找,找到a=0,所以是0,如果全局也沒有就會報錯
 6     a = 2;
 7     alert(a);    //2
 8 }
 9 fn()
10 alert(a);    //2,fn把這全局的a修改了
1 function fn(a){
2    alert(a);    //undefined,JS會把傳參當作var一樣對待,相當於在fn內部定義了一個變量--> var a;
3    a = 2;
4    alert(a);    //2,這里修改的不是全局的哦,改的是fn的局部變量哦
5 }
6 fn()
7 alert(a);    //報錯

 

1 <script>
2 alert(a);    //報錯,因為遇到<script>標簽對時,會先對這一塊進行預解析,運行到下面的才會再進行預解析,下面沒預解析,所以找不到a,於是報錯了
3 </script>
4 
5 <script>
6 alert(a);    //undefined
7 var a = 0;
8 alert(a);    //0
9 </script>
1 <script>
2 var a;    
3 </script>
4 
5 <script>
6 alert(a);    //undefined,雖然這個<script>標簽對沒有定義a,但會往上查找,上面的個<script>標簽定義了,所以為undefined
7 </script>

 

 下面我們再看下這兩種情況的區別: 

1 alert(a);    //function a(){ alert('我是函數') }
2 function a(){ alert('我是函數') }
1 alert(a);    //undefined,可以看出,凡是var,初始值都是undefined
2 var a = function (){ '我是函數' }

 

看,JS預解析也就這樣,沒我們想象中的那么難吧!

 

歡迎拍磚,覺得好的請點下推薦~~

 

之前還有一個地方不夠嚴謹,補充一下(2014.06.08):

對於函數內的預解析,可以理解成在執行前一瞬間,傳了參數后,進行預解析,然后才執行。

對於參數的預解析,傳參前,直接賦值undefined,傳參后,就是傳參的值;

所以在函數內的預解析  參數 是最先被解析到的。 

function a(b){
     //首先,執行的瞬間,傳參后進行預解析-> b = 1,然后往下找 b = b函數,最后b = b函數
	alert(b);

	function b(){
		alert(b);
	}
	b();
}
a(1);	//b函數, b函數
function a(b){
     //傳參后進行預解析 -> b = c函數,然后往下找 b = b函數,最后b = b函數   
	alert(b);

	function b(){
		alert(b);
	}
	b();
}
a(c);	//b函數,  b函數
function c(){ return 123; }

  

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM