預(yù)解析只會(huì)發(fā)生在通過var定義的變量和function上腕让。
一孤钦、原理
1. 定義:預(yù)解析:在當(dāng)前作用域下,js運(yùn)行之前歧斟,會(huì)把帶有var和function關(guān)鍵字的事先聲明,并在內(nèi)存中安排好偏形。然后再?gòu)纳系较聢?zhí)行js語(yǔ)句静袖。
2. 通俗點(diǎn)講,即認(rèn)為瀏覽器在正式運(yùn)行JavaScript代碼前俊扭,
第一步队橙,會(huì)預(yù)先根據(jù)關(guān)鍵字var、function等萨惑,來查找一些需要被解析的東西捐康,
例如:var a = 1;?function test(){?alert(2);?};?
第二步,給這些需要被解析的東西提前賦值庸蔼,其中包括:
⑴ 所有的變量解总,提前賦值:undefined;
⑵ 所有的函數(shù)姐仅,在正式運(yùn)行代碼前花枫,都賦值為整個(gè)函數(shù)塊。
第三部掏膏,“預(yù)解析”結(jié)束后劳翰,瀏覽器再逐行解讀代碼,并通過表達(dá)式:= + - * -- ++ !等來修改這些“預(yù)解析”的值馒疹。
二佳簸、解析原則
1. JavaScript “預(yù)解析”過程中,遇到重名的內(nèi)容颖变,只保留一個(gè):
⑴ 重名變量或重名函數(shù)溺蕉,保留最后的一個(gè);
⑵ 變量和函數(shù)重名悼做,只保留函數(shù)疯特;
2.根據(jù)作用域鏈,來查找上文第一步中提到的需要被解析的東西
查找原則:從上到下肛走,從里到外
即先找局部作用域里找漓雅,然后子對(duì)象會(huì)一級(jí)一級(jí)向上尋找所有父對(duì)象的變量。
三朽色、案例分析
案例一:
alert(a); //?function a(){alert(4);}
var a=1;
alert(a); //?1
function a(){alert(2);}
alert(a); //?1
var a=3;
alert(a); //?3
function a(){alert(4);}
alert(a); //?3
a(); //報(bào)錯(cuò)
分析:
1. 找出需要被解析的東西:a
2. 預(yù)解析賦值:undefined邻吞,function a( alert(2); ),undefined葫男,function a( alert(4); )
根據(jù)解析原則2抱冷,變量與函數(shù)重名保留函數(shù),則第一個(gè)alert預(yù)解析為:function a( alert(4);
3. 預(yù)解析結(jié)束梢褐,代碼開始執(zhí)行旺遮,第一個(gè)alert通過表達(dá)式賦值赵讯,則輸出預(yù)解析的值,其余均有表達(dá)式操作耿眉,依次改變?yōu)椋?边翼,3
4. 最后的a為一個(gè)變量,不能以函數(shù)的方式執(zhí)行
案例二:
var a = 1;
function test(){
alert(a); //undefined
var a = 2;
}
test();
alert(a); //1
分析:
通過var關(guān)鍵字在局部作用域里鸣剪,查找到需要被解析的變量a组底,賦值undefined。
這里注意函數(shù)的執(zhí)行順序筐骇,test函數(shù)執(zhí)行時(shí)债鸡,alert(a)并未有表達(dá)式操作,故為undefined铛纬。