首先看一段代碼
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title></title> </head> <body> <span>我是span</span> <script type="text/javascript"> alert(cnt); var cnt=60; function huoqu(){ } </script> </body> </html>
代碼的執行順序是從上往下的,當代碼執行到script標簽時,也就開始執行js代碼了。
執行js代碼一般分兩步:1.預解析代碼。 2.逐行執行代碼。
第一步:預解析代碼
預解析代碼呢,主要會把var , function , 參數等一些東西 存儲進倉庫里面(內存)。
1.var 一般用於聲明變量,預解析代碼的時候,等號后面的賦值過程不會執行,所以預解析時的var 變量 都是未定義的。
2,.function 函數呢,預解析的時候,值就是函數里面的內容。
當變量和函數重名時:就只留下函數的值,不管順序誰前誰后。所以函數的優先級比變量高。注意:這只是預解析。
當函數和函數重名時:會留下后面那個,會遵循上下文機制。
第二步:逐行執行代碼
當預解析完成之后,就開始逐行執行代碼了,全部代碼都會完整的執行。
實例:下面的alert分別會彈出什么值
1 <script> 2 alert(a); 3 var a=1; 4 function a(){alert(2);} 5 alert(a); 6 var a=3; 7 alert(a); 8 function a(){alert(4);} 9 alert(a); 10 </script>
第一步:預解析
上面說過,預解析時只會把var , function ,參數等存儲起來,所以:
執行到第二行時,a 的值是未定義。
執行到第四行時,a 的值是函數本身,也就是function a(){alert(2);}。
執行到第六行時,a 的值還是第四行時的值,也就是function a(){alert(2);},因為函數的優先級比變量高。
執行到第八行時,a 的值就變成了function a(){alert(4);} ,因為當兩個函數重名時,遵循代碼從上往下執行。
第二步:代碼逐行執行
預解析完成之后,就是代碼逐行執行了,
第二行:會彈出function a(){alert(4);} ,因為預解析完成之后,被存進內存的a 的值就是function a(){alert(4);}
第三行:第三行里有表達式,a 被賦了一個新的值1 表達式會改變變量的值。表達式可以改變預解析的值。
第四行:只是函數的聲明,並沒有用到表達式,而且也沒有函數的調用,所以不會改變a 的值。
第五行:因為a 的值沒有變化,所以還是1
第六行:使用了表達式,a 被賦了一個新的值3
第七行:會彈出3
第八行:函數的聲明,不會改變a 的值。
第九行:a的值沒有改變,所以還是3
最后結果為:
<script> 2 alert(a);//彈出function a(){alert(4)} 3 var a=1; 4 function a(){alert(2);} 5 alert(a);//彈出1 6 var a=3; 7 alert(a);//彈出3 8 function a(){alert(4);} 9 alert(a);//彈出3 10 </script>