js變量提升

**一.案發(fā)現(xiàn)場 **我們先看一段很簡單的代碼:

var v='Hello World'; alert(v);

這個沒有疑問吧,彈出“Hello World”沿猜。OK,我們繼續(xù)。

我們在看一段Code:

var v='Hello World'; (function(){ alert(v); })()

經(jīng)過運(yùn)行之后蛇尚,我們發(fā)現(xiàn),還是和我們預(yù)期的一樣顾画,彈出了“Hello World”取劫。

好了,有意思的來了研侣。接著在看一段下面的代碼:

var v='Hello World'; (function(){ alert(v); var v='I love you'; })()

如果這個是一個面試題谱邪,面試官問你這個結(jié)果是多少?你怎么回答庶诡? 我們先看結(jié)果吧惦银!



結(jié)果是 undefined?和你上面自己想的一樣嗎? 好吧璧函,我就不故弄玄虛了傀蚌。其實(shí),這里面隱藏了一個陷阱-----JavaScript中的變量提升(Hoisting)蘸吓;

二.深度剖析

現(xiàn)在我來解釋下提升是什么意思善炫?顧名思義,就是把下面的東西提到上面库继。在JS中箩艺,就是把定義在后面的東東(變量或函數(shù))提升到前面中定義。
在解釋提升之前宪萄,我們先來看一下js中的作用域(scoping)問題艺谆。
對于JavaScript新手來說scoping是最令人困惑的部分之一。事實(shí)上拜英,不僅僅是新手静汤,我遇到或很多有經(jīng)驗(yàn)的JavaScript程序員也不能完全理解scoping。JavaScript的scoping如此復(fù)雜的原因是它看上去非常像C系語言的成員居凶。請看下面的C程序:

#include <stdio.h> int main() { int x = 1; printf("%d, ", x); // 1 if (1) { int x = 2; printf("%d, ", x); // 2 } printf("%d\n", x); // 1 }

這段程序的輸出是1,2,1虫给。這是因?yàn)樵贑系語言有塊級作用域(block-level scope),當(dāng)進(jìn)入到一個塊時,就像if語句侠碧,在這個塊級作用域中會聲明新的變量抹估,這些變量不會影響到外部作用域。但是JavaScript卻不是這樣弄兜。在Firebug中試試下面的代碼:

var x = 1; console.log(x); // 1 if (true) { var x = 2; console.log(x); //2 } console.log(x);// 2

在這段代碼中药蜻,F(xiàn)irebug顯示1,2,2替饿。這是因?yàn)镴avaScript是函數(shù)級作用域(function-level scope)语泽。這和C系語言是完全不同的。塊盛垦,就像if語句湿弦,并不會創(chuàng)建一個新的作用域。只有函數(shù)才會創(chuàng)建新的作用域腾夯。

對于大部分熟悉C颊埃,C++,C#或是Java的程序員來說蝶俱,這是意料之外并且不被待見的班利。幸運(yùn)的是,因?yàn)镴avaScript函數(shù)的靈活性榨呆,對于這個問題我們有一個解決方案罗标。如果你必須在函數(shù)中創(chuàng)建一個臨時的作用域,請像下面這樣做:

function foo() { var x = 1; if (x) { (function () { var x = 2; // some other code }()); } // x is still 1. }

這種方面確實(shí)非常靈活,它使用在任何需要創(chuàng)建一個臨時作用域的地方闯割,不僅僅是某個塊中彻消。但是,我強(qiáng)烈建議你花點(diǎn)時間好好理解下JavaScript scoping宙拉。它實(shí)在是非常強(qiáng)力宾尚,而且它也是我最喜歡的語言特性之一。如果你很好的理解了scoping谢澈,理解hoisting將會更加容易煌贴。

2.1變量提升

變量提升,很簡單锥忿,就是把變量提升提到函數(shù)的top的地方牛郑。我么需要說明的是,變量提升 只是提升變量的聲明敬鬓,并不會把賦值也提升上來淹朋。
比如: 我們定義三個變量:

(function(){ var a='One'; var b='Two'; var c='Three'; })()

實(shí)際上它是這樣子的:

(function(){ var a,b,c; a='One'; b='Two'; c='Three'; })()

這個時候就把變量提升了呀。

好列林,我們現(xiàn)在回到第一段code里面瑞你。為什么會報錯呢?其實(shí)希痴,根據(jù)我么根據(jù)上面變量提升原件以及js的作用域(塊級作用域)的分析,得知 上面代碼真正變成如下:

var v="Hello World"; (function(){ var v; alert(v); v="I love you"; })()

所以春感,才會提示說“undefined”砌创。
從這里,我們也學(xué)習(xí)到鲫懒,我們在寫js code 的時候嫩实,我么需要把變量放在塊級作用域的頂端,比如我在上面所舉的例子:var a,b,c;窥岩。防止出現(xiàn)意外甲献。

2.2 函數(shù)提升

函數(shù)提升是把整個函數(shù)都提到前面去。

在我們寫js code 的時候颂翼,我們有2中寫法晃洒,一種是函數(shù)表達(dá)式,另外一種是函數(shù)聲明方式朦乏。我們需要重點(diǎn)注意的是球及,只有函數(shù)聲明形式才能被提升。

函數(shù)聲明方式提升【成功】

function myTest(){ foo(); function foo(){ alert("我來自 foo"); } } myTest();

函數(shù)表達(dá)式方式提升【失敗】

function myTest(){ foo(); var foo =function foo(){ alert("我來自 foo"); } } myTest();

結(jié)果如下:

左邊報錯了呻疹。沒騙你吃引。
應(yīng)該到這里基本都可以弄懂了。~ 呵呵。镊尺。 再次謝謝Beta Rabbit

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末朦佩,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子庐氮,更是在濱河造成了極大的恐慌吕粗,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,311評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件旭愧,死亡現(xiàn)場離奇詭異颅筋,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)输枯,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,339評論 2 382
  • 文/潘曉璐 我一進(jìn)店門议泵,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人桃熄,你說我怎么就攤上這事先口。” “怎么了瞳收?”我有些...
    開封第一講書人閱讀 152,671評論 0 342
  • 文/不壞的土叔 我叫張陵碉京,是天一觀的道長。 經(jīng)常有香客問我螟深,道長谐宙,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,252評論 1 279
  • 正文 為了忘掉前任界弧,我火速辦了婚禮凡蜻,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘垢箕。我一直安慰自己划栓,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,253評論 5 371
  • 文/花漫 我一把揭開白布条获。 她就那樣靜靜地躺著忠荞,像睡著了一般。 火紅的嫁衣襯著肌膚如雪帅掘。 梳的紋絲不亂的頭發(fā)上委煤,一...
    開封第一講書人閱讀 49,031評論 1 285
  • 那天,我揣著相機(jī)與錄音锄开,去河邊找鬼素标。 笑死,一個胖子當(dāng)著我的面吹牛萍悴,可吹牛的內(nèi)容都是我干的头遭。 我是一名探鬼主播寓免,決...
    沈念sama閱讀 38,340評論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼计维!你這毒婦竟也來了袜香?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 36,973評論 0 259
  • 序言:老撾萬榮一對情侶失蹤鲫惶,失蹤者是張志新(化名)和其女友劉穎蜈首,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體欠母,經(jīng)...
    沈念sama閱讀 43,466評論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡欢策,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,937評論 2 323
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了赏淌。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片踩寇。...
    茶點(diǎn)故事閱讀 38,039評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖六水,靈堂內(nèi)的尸體忽然破棺而出俺孙,到底是詐尸還是另有隱情,我是刑警寧澤掷贾,帶...
    沈念sama閱讀 33,701評論 4 323
  • 正文 年R本政府宣布睛榄,位于F島的核電站,受9級特大地震影響想帅,放射性物質(zhì)發(fā)生泄漏场靴。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,254評論 3 307
  • 文/蒙蒙 一博脑、第九天 我趴在偏房一處隱蔽的房頂上張望憎乙。 院中可真熱鬧,春花似錦叉趣、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,259評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至蚕礼,卻和暖如春烟具,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背奠蹬。 一陣腳步聲響...
    開封第一講書人閱讀 31,485評論 1 262
  • 我被黑心中介騙來泰國打工朝聋, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人囤躁。 一個月前我還...
    沈念sama閱讀 45,497評論 2 354
  • 正文 我出身青樓冀痕,卻偏偏與公主長得像荔睹,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子言蛇,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,786評論 2 345

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

  • 原文: https://github.com/ecomfe/spec/blob/master/javascript...
    zock閱讀 3,370評論 2 36
  • 從別人給我的一道題目說起僻他,請問執(zhí)行下面語句后的輸出結(jié)果 我最初的答案是: 其實(shí)應(yīng)該是 這道題包含了了函數(shù)提升與變量...
    superzdd閱讀 761評論 0 5
  • 概念 首先,看這篇文章之前確保你已經(jīng)理解了js作用域腊尚。其次要補(bǔ)充吨拗,js在運(yùn)行的時候,會優(yōu)先加載當(dāng)前作用域下的變量婿斥。...
    jacklin1992閱讀 963評論 1 7
  • 才接觸weex劝篷,有些坑需要踩。官方文檔寫的比較粗泛民宿,打算在這做個記錄娇妓,方便后人。 系統(tǒng)是mac系統(tǒng)所以省去了很多配...
    薄荷星球閱讀 8,887評論 1 10
  • 今晚動車上一位乘務(wù)員名字叫做管玉 名字著實(shí)好聽
    孟悟空閱讀 146評論 0 0