js基礎(chǔ)陣營(yíng):變量篇之變量,函數(shù)提升

上面已經(jīng)介紹完了變量的定義哭当,以及變量的作用域問(wèn)題猪腕,這章我們來(lái)看看變量提升的問(wèn)題。在進(jìn)行這章開(kāi)始前钦勘,我們先來(lái)探討一個(gè)很悠久的問(wèn)題陋葡,那就是
image.png

哈哈。開(kāi)玩笑彻采。言歸正傳腐缤。我們先看下面代碼

console.log(a);
var  a = 2;

輸出結(jié)果是
image.png

直覺(jué)上我們理解的是程序會(huì)從上往下,順序執(zhí)行肛响,按照這個(gè)邏輯岭粤,我們應(yīng)該得到的是這樣的
image.png

但是實(shí)際上感覺(jué)是代碼是這樣的
var a;
console.log(a);
a = 2;

為什么會(huì)這樣呢?這里就需要知道編輯器在執(zhí)行程序所需要的做的事了特笋,編輯器在執(zhí)行程序的時(shí)候會(huì)先執(zhí)行編譯剃浇,那么編譯階段有一部分的工作是找到所在作用域中的所有的聲明,所以我們可以理解為,在js中任何代碼在執(zhí)行前虎囚,其(函數(shù)角塑,變量)聲明都會(huì)被先處理。因此淘讥,我們看到var a = 2;其實(shí)在編譯器中是var a和a = 2;兩部分圃伶。var a,是在編譯階段執(zhí)行的,a = 2在執(zhí)行階段執(zhí)行适揉。這個(gè)過(guò)程就好像變量以及函數(shù)聲明從他們?cè)械拇a處被移動(dòng)了,所以叫做提升煤惩。
上面說(shuō)的是變量嫉嘀,那么函數(shù)呢?是否也會(huì)提升呢魄揉?我們來(lái)看下下面的例子

sayName();
function sayName(){
  console.log('來(lái)瓶二鍋頭');
}

將上面代碼放到控制臺(tái)剪侮,看下結(jié)果
image.png

顯而易見(jiàn),我們的函數(shù)聲明也提升了洛退,實(shí)際上在執(zhí)行的時(shí)候代碼是這樣的

function sayName(){
  console.log('來(lái)瓶二鍋頭');
}
sayName();

那么函數(shù)內(nèi)部的變量是否也會(huì)提升呢瓣俯?我們?cè)賮?lái)看下這個(gè)例子

function sayName(){
  console.log(name);
  var name = '來(lái)瓶二鍋頭';
}
sayName();

在控制臺(tái)我們看下結(jié)果
image.png

可以看到我們輸出的是undefined,而不是referenceError.所以函數(shù)中的變量也得到了提升,實(shí)際的代碼是這樣的

function sayName(){
  var name;
  console.log(name);
  name = '來(lái)瓶二鍋頭';
}
sayName();

所以前面我理解的結(jié)論 在js中任何代碼在執(zhí)行前兵怯,其(函數(shù)彩匕,變量)聲明都會(huì)被先處理是正確的。
此時(shí)我們?cè)卺槍?duì)函數(shù)來(lái)想下媒区,除了上面的函數(shù)聲明驼仪,我們?nèi)绻ㄟ^(guò)函數(shù)表達(dá)式是否會(huì)得到提升呢?看下下面的代碼

sayName();
var sayName = function (){
  console.log('來(lái)瓶二鍋頭');
}

輸出到控制臺(tái)袜漩,看下結(jié)果
image.png

此時(shí)報(bào)錯(cuò)不在referenceError而是TypeError绪爸。那么我們?cè)谠囅孪旅娴拇a看看

console.log(sayName);
var sayName = function (){
  console.log('來(lái)瓶二鍋頭');
}

在控制臺(tái)執(zhí)行下看看結(jié)果
image.png

至此大家應(yīng)該明白啥意思了吧。前面說(shuō)過(guò)了宙攻,我們會(huì)把聲明提前奠货,但是執(zhí)行的依舊在原位置,所以程序執(zhí)行前面的代碼的時(shí)候座掘,實(shí)際上是這樣的

var sayName;
sayName();
sayName = function (){
  console.log('來(lái)瓶二鍋頭');
}

這個(gè)時(shí)候递惋,sayName只是被定義了,不是一個(gè)函數(shù)溢陪,所以執(zhí)行sayName()會(huì)報(bào)TypeError丹墨,而執(zhí)行console.log(sayName);也不會(huì)報(bào)錯(cuò)
那么我們?nèi)绻ㄟ^(guò)函數(shù)表達(dá)式加具名函數(shù)一起使用,會(huì)是什么樣子呢嬉愧?一起看下下面代碼

sayName();
a();
var sayName = function a(){
  console.log('來(lái)瓶二鍋頭')
}

在控制臺(tái)執(zhí)行下贩挣,看下結(jié)果
image.png

可以看到sayName是報(bào)TypeError,但是a()是報(bào)ReferenceError錯(cuò)誤。sayName上面說(shuō)過(guò)了,那a()是為什么呢王财?我們?cè)诳聪孪旅娴拇a

var sayName = function a(){
  console.log(a);
  console.log('來(lái)瓶二鍋頭')
}
sayName();

控制臺(tái)看下結(jié)果
image.png

那么我們可以看出實(shí)際上程序在執(zhí)行的時(shí)候卵迂,代碼是下面這樣的

var sayName;
sayName = function(){
  var a = 函數(shù)本身;
  console.log(a);
  console.log('來(lái)瓶二鍋頭')
}
sayName();

所以我們從另一個(gè)角度也能得出一個(gè)結(jié)論,那就是如果函數(shù)表達(dá)式是跟著具名函數(shù)绒净,那么具名函數(shù)實(shí)際是這個(gè)方法本身见咒。在其函數(shù)作用域內(nèi)生效。是不是很神奇挂疆。那么原理具體是什么呢改览?我們?cè)诤竺娴暮瘮?shù)篇來(lái)給出解答(挖坑,看下后面是否真的可以給填上缤言,哈哈)宝当。

上面說(shuō)到了函數(shù)以及變量提升的問(wèn)題,那么我們?cè)賮?lái)思考一個(gè)問(wèn)題胆萧,那就是如果函數(shù)名和變量名相同的時(shí)候庆揩,誰(shuí)在前呢?
image.png

我們來(lái)看下下面的例子
test()
var test;
function test() {
  console.log('a');
}
test = function(){
  console.log('b');
}

控制臺(tái)執(zhí)行結(jié)果為
image.png

那么我們可以看出跌穗,在執(zhí)行過(guò)程中订晌,實(shí)際上為

function test() {
  console.log('a');
}
var test;
test();
test = function(){
  console.log('b');
}

所以我們可以得出結(jié)論,在變量以及函數(shù)相同的情況下函數(shù)優(yōu)先蚌吸。我們?cè)賮?lái)思考一個(gè)問(wèn)題锈拨,那就是變量實(shí)際上存在覆蓋的問(wèn)題,那么下面的代碼執(zhí)行的結(jié)果是啥呢?

test();
function test(){
  console.log('a');
}
var test = function(){
  console.log('b'); 
}
function test(){
  console.log('c');
}

按照我們上面說(shuō)的編譯時(shí)候提升的問(wèn)題羹唠,代碼可以理解為

function test(){
  console.log('a');
}
function test(){
  console.log('c'); 
}
var test;
test();
test = function(){
  console.log('b'); 
}

由于存在 重載推励,所以執(zhí)行結(jié)果為c。
我們?cè)賮?lái)設(shè)想一個(gè)場(chǎng)景肉迫,如果我們?cè)谄胀ǖ膲K級(jí)作用域中定義函數(shù)验辞,會(huì)怎么樣呢?看下下面的代碼

test1()
if(true){
    function test1(){
        console.log('1')
    }
}

結(jié)果為
image.png

為什么呢喊衫?我們都知道普通的塊級(jí)作用域會(huì)將變量提升到上級(jí)作用域中跌造,那么實(shí)際上代碼邏輯為

var test1;
test1();
if(true){
  test1 = function(){
   console.log('1')
  }
}

所以你懂了嗎?至此關(guān)于提升的問(wèn)題結(jié)束了族购。接下來(lái)我們將看看變量的類型一系列問(wèn)題壳贪。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市寝杖,隨后出現(xiàn)的幾起案子违施,更是在濱河造成了極大的恐慌,老刑警劉巖瑟幕,帶你破解...
    沈念sama閱讀 211,817評(píng)論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件磕蒲,死亡現(xiàn)場(chǎng)離奇詭異留潦,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)辣往,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,329評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門兔院,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人站削,你說(shuō)我怎么就攤上這事坊萝。” “怎么了许起?”我有些...
    開(kāi)封第一講書(shū)人閱讀 157,354評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵十偶,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我园细,道長(zhǎng)惦积,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 56,498評(píng)論 1 284
  • 正文 為了忘掉前任珊肃,我火速辦了婚禮荣刑,結(jié)果婚禮上馅笙,老公的妹妹穿的比我還像新娘伦乔。我一直安慰自己,他們只是感情好董习,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,600評(píng)論 6 386
  • 文/花漫 我一把揭開(kāi)白布烈和。 她就那樣靜靜地躺著,像睡著了一般皿淋。 火紅的嫁衣襯著肌膚如雪招刹。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 49,829評(píng)論 1 290
  • 那天窝趣,我揣著相機(jī)與錄音疯暑,去河邊找鬼。 笑死哑舒,一個(gè)胖子當(dāng)著我的面吹牛妇拯,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播洗鸵,決...
    沈念sama閱讀 38,979評(píng)論 3 408
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼越锈,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了膘滨?” 一聲冷哼從身側(cè)響起甘凭,我...
    開(kāi)封第一講書(shū)人閱讀 37,722評(píng)論 0 266
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎火邓,沒(méi)想到半個(gè)月后丹弱,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體德撬,經(jīng)...
    沈念sama閱讀 44,189評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,519評(píng)論 2 327
  • 正文 我和宋清朗相戀三年蹈矮,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了砰逻。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,654評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡泛鸟,死狀恐怖蝠咆,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情北滥,我是刑警寧澤刚操,帶...
    沈念sama閱讀 34,329評(píng)論 4 330
  • 正文 年R本政府宣布,位于F島的核電站再芋,受9級(jí)特大地震影響菊霜,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜济赎,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,940評(píng)論 3 313
  • 文/蒙蒙 一鉴逞、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧司训,春花似錦构捡、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,762評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至统扳,卻和暖如春喘帚,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背咒钟。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,993評(píng)論 1 266
  • 我被黑心中介騙來(lái)泰國(guó)打工吹由, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人朱嘴。 一個(gè)月前我還...
    沈念sama閱讀 46,382評(píng)論 2 360
  • 正文 我出身青樓倾鲫,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親腕够。 傳聞我的和親對(duì)象是個(gè)殘疾皇子级乍,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,543評(píng)論 2 349

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