1. 程式人生 > >js中的預編譯和作用域鏈

js中的預編譯和作用域鏈

JavaScript執行三部曲

指令碼執行js引擎都做了什麼呢?

  1. 語法分析
  2. 預編譯
  3. 解釋執行

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中找都是因為這個(作用域鏈)的原因

子 - 父 -祖宗--全域性 這樣一個(作用域鏈)的過程;