js 函數(shù)聲明與變量聲明的提升

JS是一種腳本語(yǔ)言,和一些高級(jí)語(yǔ)言不同,它沒(méi)有完整編譯的過(guò)程荤牍,一般是邊寫邊編譯,這也是我們覺(jué)得腳本語(yǔ)言比其他語(yǔ)言加載快的原因庆冕,JS中有變量聲明提升這一機(jī)制康吵。

當(dāng)JS在執(zhí)行的時(shí)候會(huì)分為2個(gè)階段,預(yù)解析访递,執(zhí)行晦嵌,當(dāng)JS在執(zhí)行的時(shí)候會(huì)將所有用var聲明的變量以及關(guān)鍵字定義的函數(shù)進(jìn)行提升( function fn(){......} ),提升到當(dāng)前作用域的最頂端拷姿,而賦值語(yǔ)句在原地等待執(zhí)行惭载,預(yù)解析后,再?gòu)纳贤轮鹦薪馕龃a响巢。預(yù)解析遵循一些原則描滔,下面一點(diǎn)一點(diǎn)的說(shuō)明。

提到變量聲明提升踪古,就得結(jié)合作用域來(lái)分析含长,也就是局部作用域能訪問(wèn)到全局的變量券腔,而全局作用域訪問(wèn)不到局部作用域。

1. 函數(shù)聲明提升

函數(shù)的聲明方式

函數(shù)聲明有兩種方式:函數(shù)聲明拘泞,函數(shù)表達(dá)式(又稱函數(shù)字面量聲明)

  1. 函數(shù)聲明提升會(huì)在編譯階段把聲明和函數(shù)體整體都提前到執(zhí)行環(huán)境頂部纷纫,所以我們可以在函數(shù)聲明之前調(diào)用這個(gè)函數(shù)
  2. 函數(shù)表達(dá)式,其實(shí)就是變量聲明的一種田弥,聲明關(guān)鍵字會(huì)被提升到執(zhí)行環(huán)境頂部涛酗,并賦值undefined。賦值語(yǔ)句被留在原地等到執(zhí)行偷厦。

①函數(shù)聲明的提升

// 函數(shù)聲明
func()
function func () {
  console.log(1);
}

上例不會(huì)報(bào)錯(cuò)商叹,因?yàn)?‘函數(shù)聲明提升’,即將函數(shù)聲明提升(整體)到作用域頂部只泼,實(shí)際提升后結(jié)果同下:

// 函數(shù)聲明提升后
function func () {
}
func() // 1

②函數(shù)表達(dá)式的提升

 // 函數(shù)表達(dá)式
baz(); 
var baz = function(){
      console.log(1);
}

上例會(huì)報(bào)錯(cuò)輸出TypeError: baz is not a function
函數(shù)表達(dá)式聲明提升后剖笙,只會(huì)把聲明操作var baz提升到頭部,其他的賦值部分函數(shù)體還留在原地请唱,實(shí)際提升后結(jié)果同下:

//函數(shù)表達(dá)式的提升后
var baz;
baz(); // TypeError: baz is not a function
baz = function() {
    console.log(1);
 };

2. 變量聲明提升

變量聲明提升(只有var聲明的變量才有變量提升弥咪,let、const無(wú)十绑;變量賦值無(wú)提升)
變量聲明提升會(huì)把var聲明的頭部提升聚至,賦值部分留在原地

1.簡(jiǎn)單的變量聲明提升
console.log(num)
var num = 10

上例輸出undefined,變量聲明提升會(huì)把var num提升本橙,賦值部分num = 10留在原地

// 變量聲明提升后
var num 
console.log(num)
num = 10
2.函數(shù)內(nèi)的變量聲明提升

①舉例1

var a=1;
function fn(){
    console.log(a);
    a=2;
}
fn();      
console.log(a);

結(jié)果先輸出1扳躬,后輸出2

解析:當(dāng)fn執(zhí)行后,會(huì)輸出1甚亭,因?yàn)榫植孔饔糜蚰茉L問(wèn)到全局作用域贷币,代碼逐行執(zhí)行,向上尋找亏狰,找到全局變量a = 1役纹,當(dāng)再次console.log(a)時(shí),a = 2暇唾,修改里全局變量a促脉,所以a = 2(如果函數(shù)內(nèi)部不用var聲明a,直接a=2策州,此時(shí)a相當(dāng)于全局變量)

②舉例2

var a = 1;
function fn(){
    console.log(a);
    var a=2;
}
fn();      
console.log(a);

結(jié)果先輸出undefined瘸味,后輸出1

解析:當(dāng)fn執(zhí)行后,會(huì)把函數(shù)內(nèi)部的var聲明的變量提升抽活,所以輸出undefined,console.log(a)取全局變量a = 1

// 變量提升后
var a = 1;
function fn(){
    var a
    console.log(a);
    a=2;
}
fn();      // undefined
console.log(a); // 1

③舉例3

var a=1;
function fn(a){
 console.log(a);
 a=2;
}
fn();   // undefined
console.log(a);  // 1

結(jié)果輸出又不一樣 锰什,此時(shí)執(zhí)行fn函數(shù)下硕,函數(shù)傳一個(gè)參數(shù)丁逝,就相當(dāng)于在函數(shù)內(nèi)聲明了一個(gè)變量,由于fn()沒(méi)有傳參梭姓,所以輸出undefined霜幼,注意此時(shí)函數(shù)內(nèi)部的a =2是函數(shù)內(nèi)部變量也就是參數(shù)a,不是全局變量誉尖。console.log(a)罪既,輸出全局變量 1

別暈,再看一個(gè)例題

④舉例4

var a=1;
function fn(a){
 alert(a);
 a=2;
}
fn(a);  // 1
alert(a);  // 1

結(jié)果又是什么呢铡恕?
函數(shù)輸出1琢感,因?yàn)楹瘮?shù)調(diào)用的時(shí)候把全局的a傳了進(jìn)去,即fn(1)探熔,所以函數(shù)內(nèi)部a = 1驹针,,全局仍然輸出1

3.函數(shù)聲明與變量聲明先后順序

函數(shù)聲明會(huì)優(yōu)于變量的聲明诀艰,也就是說(shuō)函數(shù)會(huì)提升到變量的前面

var c = 1;
function d() {
    console.log(c);
    var c = 2;
}
d();

結(jié)果輸出 undefined 柬甥,函數(shù)整體提升到全局變量var c = 1前面,函數(shù)內(nèi)部的var c提升其垄,結(jié)果如下

// 提升后
function d() {
    var c
    console.log(c);
    c = 2;
}
var c = 1;
d(); // undefined 

4.課后習(xí)題

console.log(a);
var a=1;
console.log(a);
function a(){console.log(2)}
console.log(a);
var a=3;
console.log(a)
function a(){console.log(4)}
console.log(a)
a();

第一看到這些代碼誰(shuí)都頭大苛蒲,不過(guò)我們來(lái)一點(diǎn)一點(diǎn)的看。

從上往下看绿满,遇到var a = 1臂外,提升var a ,a = 1留在原地

var a
console.log(a);
a=1;
console.log(a);
function a(){console.log(2)}
console.log(a);
var a=3;
console.log(a)
function a(){console.log(4)}
console.log(a)
a();

繼續(xù)往下棒口,遇到函數(shù)function a(){console.log(2)}寄月,整體提升,把var a替代

function a(){console.log(2)}
console.log(a);
a=1;
console.log(a);
console.log(a);
var a=3;
console.log(a)
function a(){console.log(4)}
console.log(a)
a();

繼續(xù)往下无牵,遇到函數(shù)var a=3漾肮,當(dāng)遇到重名的變量只會(huì)留一個(gè),遇到函數(shù)茎毁,函數(shù)的優(yōu)先級(jí)高克懊,所以留函數(shù),繼續(xù)遇到函數(shù)function a(){console.log(4)}七蜘,提升谭溉,替換function a(){console.log(2)}

function a(){console.log(4)}
console.log(a);
a=1;
console.log(a);
console.log(a);
a=3;
console.log(a)
console.log(a)
a();

最后a(),想上找a ,找到a = 3橡卤,不是函數(shù)報(bào)錯(cuò)
輸出結(jié)果扮念,function a(){console.log(4)} 1 1 3 3 a is not a function

看到這里是不是對(duì)變量和函數(shù)的提升有了進(jìn)一步的了解了呢

文字參考: https://www.cnblogs.com/lzn0330/p/9709654.html

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市碧库,隨后出現(xiàn)的幾起案子柜与,更是在濱河造成了極大的恐慌巧勤,老刑警劉巖,帶你破解...
    沈念sama閱讀 212,816評(píng)論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件弄匕,死亡現(xiàn)場(chǎng)離奇詭異颅悉,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)迁匠,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,729評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門剩瓶,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人城丧,你說(shuō)我怎么就攤上這事延曙。” “怎么了芙贫?”我有些...
    開(kāi)封第一講書(shū)人閱讀 158,300評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵搂鲫,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我磺平,道長(zhǎng)魂仍,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 56,780評(píng)論 1 285
  • 正文 為了忘掉前任拣挪,我火速辦了婚禮擦酌,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘菠劝。我一直安慰自己赊舶,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,890評(píng)論 6 385
  • 文/花漫 我一把揭開(kāi)白布赶诊。 她就那樣靜靜地躺著笼平,像睡著了一般。 火紅的嫁衣襯著肌膚如雪舔痪。 梳的紋絲不亂的頭發(fā)上寓调,一...
    開(kāi)封第一講書(shū)人閱讀 50,084評(píng)論 1 291
  • 那天,我揣著相機(jī)與錄音锄码,去河邊找鬼夺英。 笑死,一個(gè)胖子當(dāng)著我的面吹牛滋捶,可吹牛的內(nèi)容都是我干的痛悯。 我是一名探鬼主播,決...
    沈念sama閱讀 39,151評(píng)論 3 410
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼重窟,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼载萌!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 37,912評(píng)論 0 268
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤扭仁,失蹤者是張志新(化名)和其女友劉穎可缚,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體斋枢,經(jīng)...
    沈念sama閱讀 44,355評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,666評(píng)論 2 327
  • 正文 我和宋清朗相戀三年知给,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了瓤帚。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,809評(píng)論 1 341
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡涩赢,死狀恐怖戈次,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情筒扒,我是刑警寧澤怯邪,帶...
    沈念sama閱讀 34,504評(píng)論 4 334
  • 正文 年R本政府宣布,位于F島的核電站花墩,受9級(jí)特大地震影響悬秉,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜冰蘑,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 40,150評(píng)論 3 317
  • 文/蒙蒙 一和泌、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧祠肥,春花似錦武氓、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,882評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)剂桥。三九已至忠烛,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間渊额,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,121評(píng)論 1 267
  • 我被黑心中介騙來(lái)泰國(guó)打工寿弱, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人按灶。 一個(gè)月前我還...
    沈念sama閱讀 46,628評(píng)論 2 362
  • 正文 我出身青樓症革,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親鸯旁。 傳聞我的和親對(duì)象是個(gè)殘疾皇子噪矛,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,724評(píng)論 2 351

推薦閱讀更多精彩內(nèi)容