var a=1;
function test() {
? ? console.log(a)//function a(b){a=b}
? ? try{
? ? ? ? a(3)//a=3
? ? ? ? a()//執(zhí)行catch
? ? }catch (e){
? ? ? ? a=2
? ? }
? ? function a(b) {
? ? ? ? a=b;
? ? }
? ? console.log(++a)//3
}
test()
console.log(a)//1
有許多同學(xué)知道js在執(zhí)行的時(shí)候煤辨,是從上到下,從左到右膊夹,一行一行執(zhí)行的岳遥,但是不知道在這之前還要做一些事情乡洼,js程序在正式執(zhí)行之前邮旷,會(huì)將所有var 聲明的變量和function聲明的函數(shù)渗饮,預(yù)讀到所在作用域的頂部蚕冬,但是對(duì)var 聲明只是將聲明提前,賦值仍然保留在原位置疆瑰,function 聲明眉反,會(huì)將函數(shù)名稱和函數(shù)體都提前昙啄,而且先預(yù)聲明變量再預(yù)定義函數(shù)。這個(gè)過程也被叫做寸五,“預(yù)解析”或者“預(yù)編譯
舉例1
console.log(a);? //不會(huì)出錯(cuò)梳凛,會(huì)輸出undefinedvar a=100;
console.log(a); //100;
由于聲明提前,所以代碼會(huì)變成這樣
var a;? //聲明提前console.log(a);//undefineda=100; //賦值任然留在原位置console.log(a);//100
舉例2 聲明提前僅能將聲明提前到所在作用域的頂部
functionfn(){? ? console.log(a); //undefined? ? var a=100;
? ? console.log(a); //100 };
fn();
console.log(a);//? 報(bào)引用錯(cuò)誤播歼!
上面的代碼 其實(shí)會(huì)變成這樣
functionfn(){? ? var a;? //僅僅提前到函數(shù)頂部? ? console.log(a);? //undefined? ? a=100;
? ? console.log(a); //100};
fn();
console.log(a); //報(bào)引用錯(cuò)誤
舉例3 函數(shù)聲明提前不同于var 變量聲明提前伶跷,使用函數(shù)聲明語句掰读,函數(shù)名稱和函數(shù)體均會(huì)被提前秘狞,也就是說可以在聲明一個(gè)JavaScript函數(shù)之前調(diào)用它。
console.log(fn());? //2functionfn(){? ? return 2;
}
練習(xí)題1
var a=123;function a(){ return 1 }
console.log(a);
解析1:?
這道題在弄明白什么是 “聲明提前”后比較簡單做蹈集!?
按照剛才講到的概念烁试,這道題會(huì)變成這樣,
var a;function a(){ return 1 }
a=123;
console.log(a);
所以最后會(huì)輸出 123
練習(xí)題2
function a(){ return 1 }var a;
a();
解析2?
完成這道題拢肆,還需要知道一件事情减响,如果未在var聲明語句中給變量指定初始值,那么雖然聲明這個(gè)變量郭怪,但在給它存入一個(gè)值之前支示,它的初始值就是undefined,但是多次聲明同一變量無所謂1刹拧K毯琛!所以這道題的結(jié)果是 1
代碼會(huì)預(yù)編譯為:
var a;? //初始值為 undefinedfunction a(){ return 1 }
a();
練習(xí)題3
function a(){ return 1 }var a=undefined;
a();
解析3?
這道題攒庵,和第2題非常的相似嘴纺,只需要明白這里 var a=undefined; 和 var a;是不同的,一個(gè)是聲明變量同時(shí)進(jìn)行賦值操作浓冒,只是賦的值是undefined栽渴,一個(gè)是單純的聲明變量。?
代碼會(huì)預(yù)編譯為:
var a; //初始值為 undefinedfunction a(){ return 1 }
a=undefined;
a();
所以最后的結(jié)果會(huì)報(bào)錯(cuò) a is not a function
練習(xí)題4
if(!("a"in window)) {
? ? var a = 1;
};var a;
alert(a);
解析4:?
首先說一句稳懒,在瀏覽器中闲擦,var聲明的全局變量是屬于window對(duì)象的屬性。也就是說可以用 . 或者[]顯示出來(window.變量名 或者 window[“變量名”])场梆。?
in 運(yùn)算符 是判斷對(duì)象是否為數(shù)組/對(duì)象的元素/屬性:?
格式:(變量 in 對(duì)象)?
注意:?
當(dāng)“對(duì)象”為數(shù)組時(shí)墅冷,“變量”指的是數(shù)組的“索引”;?
當(dāng)“對(duì)象”為對(duì)象時(shí)辙谜,“變量”指的是對(duì)象的“屬性”俺榆;?
這道題也就是再說,如果 window里沒有屬性a装哆,就聲明一個(gè)變量a罐脊,然后賦值為1定嗓,最后彈出一個(gè)警告框顯示a,當(dāng)我們把這些概念弄清楚萍桌,會(huì)發(fā)現(xiàn)這道題其實(shí)是這樣的宵溅,
var a;if (!("a" in window)) {
a = 1;
};
alert(a);
這樣看,我們能很清楚的看明白上炎,在執(zhí)行if語句之前恃逻,是已經(jīng)聲明了變量a的,它的初始值是undefined藕施,所以window里是有屬性a的寇损,那么if語句執(zhí)行的條件就不滿足,無法對(duì)變量a進(jìn)行賦值裳食,所以最后也會(huì)彈出undefined