雖然,ES6在我們工作中應用得越來越廣泛,但是還是很多項目保留著ES5的寫法,所以,今天,帶著大家重新鞏固下ES5下的作用域及預解析機制。
作用域:域,指的是一個空間、范圍、區(qū)域,作用指的是在域內(nèi)可進行讀寫操作。一個變量的作用域是程序源代碼中定義的這個變量的區(qū)域。
在ES5中,只存在全局和函數(shù)級作用域,在ES6中,引入了塊級作用域,js的預解析機制大概分為兩個過程:預解析和自上而下逐行解讀
預解析:js解析器會先把var定義的變量、function、參數(shù)等一些東西存儲進倉庫里面(內(nèi)存)。變量var在正式運行之前,都賦值為undefined,function函數(shù)在運行之前,就是整個函數(shù)塊
表達式=、+、-、*、/、++、--、!、%.....number()、參數(shù)都可以賦值
遇到重名的,只留下一個,變量和函數(shù)重名,函數(shù)優(yōu)先級高于變量,只留下函數(shù)
函數(shù)調(diào)用(函數(shù)是一個作用域,遇到作用域都會按照先進行預解析,然后逐行解讀的過程執(zhí)行),先局部找參數(shù),局部找不到就自下向上找(作用域鏈)
概念扯了一大段,估計初學者還是有點暈乎乎,老司機就可以提前下車了,接下來,咋們舉幾個小栗子,結(jié)合上面的理論,深入理解。
例1:
alert(a); //error: a is not defineda = 3;
分析:
預解析
上面說過,預解析時只會把var 、 function 、參數(shù)等存儲起來,所以:
整個作用域沒有找到var function 參數(shù)
逐行解讀
預解析后,內(nèi)存中存在a且被賦值了underfind整個變量,所有,代碼執(zhí)行過程中程序直接報錯。
例2:
alert(a); //undefinedvar a = 3;
分析:
預解析
上面說過,預解析時只會把var 、 function 、參數(shù)等存儲起來,所以:
執(zhí)行到第二行時,a 的值是未定義。
逐行解讀
第一行:預解析后,內(nèi)存中存在a且被賦值了underfined
例3:
alert(a); // function a (){ alert(4); }var a = 1;alert(a); // 1function a (){ alert(2); }alert(a); // 1var a = 3; alert(a); // 3function a (){ alert(4); }alert(a); // 3分析:
域解析
上面說過,預解析時只會把var 、 function 、參數(shù)等存儲起來,所以:
執(zhí)行到第二行時,a 的值是未定義。
執(zhí)行到第四行時,a 的值是函數(shù)本身,也就是function a(){alert(2);}。
執(zhí)行到第六行時,a 的值還是第四行時的值,也就是function a(){alert(2);},因為函數(shù)的優(yōu)先級比變量高。
執(zhí)行到第八行時,a 的值就變成了function a(){alert(4);} ,因為當兩個函數(shù)重名時,遵循代碼從上往下執(zhí)行。
|
新聞熱點
疑難解答
圖片精選