1. 程式人生 > >JavaScript中的預編譯

JavaScript中的預編譯

JavaScript 預編譯

JavaScript執行三部曲:

1.語法分析: 先全部掃一遍 看有沒有語法錯誤. 2.預編譯(執行前一刻) : 函式宣告整體提升 變數 宣告提升

函式宣告整體提升(相當於提升到程式的最前面) 一個變數被聲明後,變數宣告提升(相當於把變數宣告語句放到最前,賦值不變) JavaScript的函式作用域是指在函式內宣告的所有變數在函式體內始終是有定義的,也就是說變數在宣告之前已經可用, 所有這種特性稱為宣告提前(hoisting),即JavaScript函式裡的所有宣告(只是宣告,但不涉及賦值)都被提前到函 數體的頂部,而變數賦值操作留在原來的位置 函式宣告整體提升,函式宣告語句將會被提升到外部指令碼或者外部函式作用域的頂部 聲明瞭一個變數,同時又聲明瞭一個同名函式,則會先執行變數宣告提升,再進行函式宣告整體提升 注:以上結論並不完全正確,在複雜情況下上述結論會失效

3.解釋執行: (解釋一行執行一行)

在預編譯發生前的前奏:

1.imply global 暗示全域性變數:即任何變數,如果變數未經宣告就賦值,此變數就為全域性物件所擁有。 eg:

a = 123;
console.log(a);---->123

因為變數a未經宣告就賦值了,所以變數a就為全域性變數所擁有,就是歸window所擁有。 上面的語句也可以寫同於:

a = 123;
console.log(window.a);---->123

2.一切宣告的全域性變數,全是window的屬性。 eg:

var a = 123;---->window.a = 123;

下面就是預編譯的重點:

1.建立AO物件

2.找形參和變數宣告,將變數和形參名作為AO屬性名,值為undefined

3.將實參值和形參統一

4.在函式體裡面找函式宣告,值賦予函式體

下面就以以下例子說明:

 function fn(a) {
	 	console.log(a);-->function a () {}
	 
	 	var a = 123;

	 	console.log(a);-->123
	 	
	 	function a () {}

	 	console.log(a);-->123
	 	
	 	var b = function () {}

	 	console.log(b);-->function () {}

	 	function d() {}
	 }
	 fn(1);

解題步驟: 1.首先建立AO物件: AO{

} 2.找形參和變數宣告,將變數和形參名作為AO屬性名,值為undefined AO{ a:undefined b:undefined d:undefined } 3.將實參值和形參統一: AO{ a:1 b:undefined d:undefined } 4.4.在函式體裡面找函式宣告,值賦予函式體 AO{ a:function a () {} b:function () {} d:function d () {} }

 function test(a,b) {
	 	console.log(a);-->1
	 	c = 0;
	 	var c;
	 	a = 3;
	 	b = 2;
	 	console.log(b);-->2
	 	function b() {}
	 	function d() {}
	 	console.log(b);-->2
	 }
	 test(1);

解題步驟: 1.首先建立AO物件: AO{

} 2.找形參和變數宣告,將變數和形參名作為AO屬性名,值為undefined AO{ a:undefined b:undefined c:undefined } 3.將實參值和形參統一: AO{ a:1 b:undefined c:undefined } 4.4.在函式體裡面找函式宣告,值賦予函式體 AO{ a:1 b:function b () {} c:undefined d:function d () {} } 關於在有關全域性變數下的預編譯:

a = 100;
	 function demo(e) {
	 	function e() {}
	 	arguments[0] = 2;
	 	console.log(e);-->2
	 	if (a) {
	 		var b = 123;
	 		function c(){

	 		}
	 	}
	 	var c;
	 	a = 10;
	 	var a;
	 	console.log(b);-->undefimed
	 	f = 123;
	 	console.log(c);-->undefined,因為在If語句巢狀函式,是語法錯誤的,所以function c(){}不能執行
	 	console.log(a);-->10
	 }
	 var a;
	 demo(1);
	 console.log(a);-->100
	 console.log(f);-->123

關於全域性物件。用GO建立: GO{

 }
 GO{
   a:undefined
   demo:undefined
   f:undefined
}
GO{
   a:100
   demo:function () {}
   f:123
}

AO{

} AO{ e:undefined b:undefined c:undefined a:undefined } } } AO{ e:2 b:undefined c:undefined a:undefined } AO{ e:2 b:undefined c:undefined/function c(){} a:10 }

總結:

預編譯的四個步驟很重要 1.建立AO物件 2.找形參和變數宣告,將變數和形參名作為AO屬性名,值為undefined 3.將實參值和形參統一 4.在函式體裡面找函式宣告,值賦予函式

預編譯(指令碼程式碼塊script執行前)

1.找全域性變數宣告(包括隱式全域性變數宣告,省略var宣告),變數名作全域性物件的屬性,值為undefined 2.找函式宣告,函式名作為全域性物件的屬性,值為函式引用