js中的預編譯和作用域鏈
阿新 • • 發佈:2018-11-11
JavaScript執行三部曲
指令碼執行js引擎都做了什麼呢?
- 語法分析
- 預編譯
- 解釋執行
1.語法分析分析語法是不是錯了
2,在語句執行的時候會進行預編譯
3.在編譯完了進行語句執行
下面就是編譯的主要步驟
三。預編譯的過程(分四步):
1.(對函式)建立AO物件;(對全域性的時候也就是Window)建立GO物件
2.找形參和變數宣告,將變數名和形參名作為AO屬性名,或GO物件 初始值為undefined
3.將實參值傳遞形參統一
4.在函式體裡面找變數宣告,值賦予函式體
在預編譯和執行的過程會對賦值語句會對AO,GO中的變數進行覆蓋,應該以執行結束後的結果為最終的變數標準。
當出現同命的時候函式為什麼會覆蓋變數應為函式是第4步變數是第二步就複製了,所以會函式的優先順序高
下面是一個例子的全過程:
<script type="text/javascript"> global = 100; function fn(){ console.log(global); //undefined global = 200; console.log(global); //200 var global = 300; } fn(); var global; </script> 1.首先全域性物件建立GO執行上下文 GO{ 2.對形參和變數宣告,將其作為屬性名,值為undefined global:undefined --執行後-->100 3.全域性物件沒有形參 4.在函式體裡找函式宣告,值賦予函式體 fn:function fn(){}; } 執行全域性 1. global = 100 2.fn();(先預編譯fn(),在執行) (函式預編譯產生AO上下文) AO{ 2.對形參和變數宣告,將其作為屬性名,值為undefined global:undefined --fn的AO執行到第二句-->200 --fn的AO執行到第四句-->300 3.沒形參 4.沒函式宣告 } A0執行{ 第一句:console.log(global); //undefined在AO的執行上線中global:undefined; 第二句:global = 200; 第三句:console.log(global); //在AO中找global已經變成了200 第四句:global = 300; // } 所以最後我們的 GO{ global:100 fn:function fn(){}; } AO{ global:300 }
只有把這個看懂了(看懂一點也沒關係)下面我們來寫什麼是作用域鏈 ,看完了什麼是作用域鏈
函式也是一個物件在這個物件中有些我們可以訪問的屬性比如prototype,name,不可以訪問的有[[scope]]屬性
[[scope]]屬性:指的就是我們所說的作用域,其中儲存了執行期上下文的集合
作用域鏈:[[scope]]中儲存的執行期上下文物件的集合,這個集合呈鏈式連結,也叫作用域鏈
下面看一個例子
function a(){ function b(){ var b = 234; } var a= 123; b(); } var glob = 100; a();
在b定義的時候a馬上快執行完的時候的影象
首先b會繼承了aAO和GO
在b自己執行的時候會變成(圖二)
scope chain中的數值代表數值的key,key代表:
0 ---自己的AO(Activation Object)
1---b的AO
2---GO(Clobal Object)
因為這樣才會出現說b找不到的變數可以到a中找,但a不到以到b中找都是因為這個(作用域鏈)的原因
子 - 父 -祖宗--全域性 這樣一個(作用域鏈)的過程;