JavaScript 中的提升(Hoisting)

前言:

JS中在聲明函數(shù)與變量的時候是存在變量提升的問題,一不注意符糊,有的時候會導(dǎo)致一些bug,本文主要就是針對JS中的提升問題蜜笤。JS中的提升濒蒋,分為變量提升與函數(shù)提升,并且函數(shù)提升是優(yōu)先于變量提升的把兔。當(dāng)然此文討論的內(nèi)容不包括ES6沪伙。

提升的概念

其實針對這個概念,私以為可以簡單的理解為JS解析器將函數(shù)的聲明與變量的聲明提升到所在作用域的頂部县好,以方便使用围橡。注意,只是將聲明提前缕贡,賦值并沒有提前翁授。

實例說明
console.log(a); // undefined
console.log(b); // function b() {alert(98);}
b(); // 98
function b() {
  console.log(98);
}

var a = 97;

上面的例子其實就相當(dāng)于是:

function b() {
  alert(98);
}

var a;
b(); // 98
console.log(a); // undefined
console.log(b); // function b() {alert(98);}
a = 97;
塊中的提升

在JS的塊中聲明函數(shù)的時候拣播,出現(xiàn)的了比較有趣的現(xiàn)象:

console.log(a); // undefined
console.log(b); // undefined
console.log(c); // undefined
console.log(d); // undefined

// b() //不注釋掉會報錯

if (true) {
  var a = 97;
  b(); // 98
  function b() {
    console.log(98);
  }
} else {
  var c = 99;
  function d() {
    console.log(100);
  }
}
console.log(a, b, c, d);
// a = 97
// b = function b() {console.log(98)}
// c = undefined
// d = undefined

現(xiàn)在這個情況就有點意思了:

因為JS是不存在塊級作用域的,所以變量 a 和 c 打印出來 undefined 是很好理解的收擦,但是 b 和 d 是什么情況呢贮配?
為什么也是 undefined 呢?這到底是提升了還是沒提升呢塞赂?

經(jīng)過查閱資料泪勒,我認(rèn)為這塊是瀏覽器的一種容錯機(jī)制的結(jié)果(未針對所有瀏覽器的不同版本進(jìn)行測試,如果有錯誤宴猾,希望留言斧正圆存,謝謝)。因為嚴(yán)格來說仇哆,在塊中聲明函數(shù)屬于無效語法沦辙,JS引擎會嘗試修正錯誤,將其轉(zhuǎn)化為合理的狀態(tài)(這點在《JavaScript高級程序設(shè)計 第三版》176頁也是一筆帶過)讹剔。

我認(rèn)為油讯,瀏覽器嘗試修正的時候是將函數(shù)申明轉(zhuǎn)化為函數(shù)表達(dá)式,并放在塊的最頂部延欠。所以函數(shù)的變量名進(jìn)行了提升撞羽,而函數(shù)體其實只是一種折中的提升

// 上邊代碼相當(dāng)于是這樣
var a;
var b;
var c;
var d;

if (true) {
  b = function b() {
    console.log(98);
  };
  a = 97;
  b(); // 98
} else {
  d = function () {
    console.log(100);
  }
  c = 99;
}
// 受限于水平,如有錯誤衫冻,歡迎留言斧正,謝謝

針對這種情況谒出,強(qiáng)烈不建議在塊中出現(xiàn)函數(shù)聲明隅俘,建議改為函數(shù)表達(dá)式。

總結(jié)

只要記住這個關(guān)鍵的點笤喳,其他的類似這樣題目都會迎刃而解为居,當(dāng)然搞懂這個不是為了做題,而是為了避免一些工作中的bug杀狡,所以推薦以后在寫代碼的時候蒙畴,最好按照如下的格式去書寫

function fun() {
  // 聲明各種變量
  // 聲明函數(shù)
  // 其他語句
}
參考鏈接:

JavaScript Scoping and Hoisting
Firefox doesn’t hoist function declarations in blocks

本文為作者原創(chuàng),版權(quán)所有呜象,轉(zhuǎn)載請注明出處膳凝。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市恭陡,隨后出現(xiàn)的幾起案子蹬音,更是在濱河造成了極大的恐慌,老刑警劉巖休玩,帶你破解...
    沈念sama閱讀 218,546評論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件著淆,死亡現(xiàn)場離奇詭異劫狠,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)永部,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,224評論 3 395
  • 文/潘曉璐 我一進(jìn)店門独泞,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人苔埋,你說我怎么就攤上這事懦砂。” “怎么了讲坎?”我有些...
    開封第一講書人閱讀 164,911評論 0 354
  • 文/不壞的土叔 我叫張陵孕惜,是天一觀的道長。 經(jīng)常有香客問我晨炕,道長衫画,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,737評論 1 294
  • 正文 為了忘掉前任瓮栗,我火速辦了婚禮削罩,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘费奸。我一直安慰自己弥激,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 67,753評論 6 392
  • 文/花漫 我一把揭開白布愿阐。 她就那樣靜靜地躺著微服,像睡著了一般。 火紅的嫁衣襯著肌膚如雪缨历。 梳的紋絲不亂的頭發(fā)上以蕴,一...
    開封第一講書人閱讀 51,598評論 1 305
  • 那天,我揣著相機(jī)與錄音辛孵,去河邊找鬼丛肮。 笑死,一個胖子當(dāng)著我的面吹牛魄缚,可吹牛的內(nèi)容都是我干的宝与。 我是一名探鬼主播,決...
    沈念sama閱讀 40,338評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼冶匹,長吁一口氣:“原來是場噩夢啊……” “哼习劫!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起嚼隘,我...
    開封第一講書人閱讀 39,249評論 0 276
  • 序言:老撾萬榮一對情侶失蹤榜聂,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后嗓蘑,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體须肆,經(jīng)...
    沈念sama閱讀 45,696評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡匿乃,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,888評論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了豌汇。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片幢炸。...
    茶點故事閱讀 40,013評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖拒贱,靈堂內(nèi)的尸體忽然破棺而出宛徊,到底是詐尸還是另有隱情,我是刑警寧澤逻澳,帶...
    沈念sama閱讀 35,731評論 5 346
  • 正文 年R本政府宣布闸天,位于F島的核電站,受9級特大地震影響斜做,放射性物質(zhì)發(fā)生泄漏苞氮。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,348評論 3 330
  • 文/蒙蒙 一瓤逼、第九天 我趴在偏房一處隱蔽的房頂上張望笼吟。 院中可真熱鬧,春花似錦霸旗、人聲如沸贷帮。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,929評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽撵枢。三九已至,卻和暖如春精居,著一層夾襖步出監(jiān)牢的瞬間诲侮,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,048評論 1 270
  • 我被黑心中介騙來泰國打工箱蟆, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人刮便。 一個月前我還...
    沈念sama閱讀 48,203評論 3 370
  • 正文 我出身青樓空猜,卻偏偏與公主長得像,于是被迫代替她去往敵國和親恨旱。 傳聞我的和親對象是個殘疾皇子辈毯,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,960評論 2 355

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