聲明的提升

首先先下個(gè)結(jié)論,javascript代碼在執(zhí)行時(shí)表面并不是由上到下一行一行執(zhí)行的。

什么是聲明的提升?

1.眾所周知var a;如果a不賦值的話,a的值為undefined。

var a;
console.log(a); // undefined
  1. 未聲明直接賦值的變量
a = 1;
console.log(a); // 1

上面的代碼塊為什么打印的是1,而不是undefined呢?很明顯a是聲明了的,但是a聲明在全局作用域了還是局部作用域了呢?

  1. 在局部作用域給未聲明的變量賦值
(function() {
  a = 1;
})()
console,log(a); // 1

這時(shí)可以得到結(jié)論:變量a被聲明為了全局變量

下面回到正題:

a = 1;
var a;
console.log(a); // 1

這時(shí)候a的值為1,是為什么呢?還是因?yàn)閍被聲明為全局變量了么?先來(lái)看下一個(gè)例子:

(function() {
  a = 1;
  var a;
  console.log(a); // 1
})();
console.log(a); // ReferenceError

很奇怪,第二個(gè)console的結(jié)果a是未被定義的。現(xiàn)在回想或者到文章開(kāi)頭看看一開(kāi)始的結(jié)論,是不是明白了點(diǎn)什么。那代碼執(zhí)行真正的順序是什么樣的呢?往下看

console.log(a); // undefined
var a = 1;

a的值是undefined,說(shuō)明a在console之前就已經(jīng)聲明了,但是并沒(méi)有賦值。上面代碼塊可以理解為一下代碼:

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

現(xiàn)在可以有第二個(gè)結(jié)論了:

引擎會(huì)在解釋 JavaScript 代碼之前首先對(duì)其進(jìn)行編譯。編譯階段中的一部分工作就是找到所有的聲明,并用合適的作用域?qū)⑺鼈冴P(guān)聯(lián)起來(lái)。所以正確的思路應(yīng)該是: 所有變量的聲明都會(huì)在任何代碼被執(zhí)行前首先被處理(函數(shù)也一樣)。

當(dāng)我們看到var a = 1;時(shí),javascript其實(shí)是將它看成兩個(gè)語(yǔ)句:var a; 和 a = 1; 聲明是在編譯階段進(jìn)行的,而賦值操作等待在原地等待被執(zhí)行。這就叫提升。

注意:提升只會(huì)提升到當(dāng)前作用域!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

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

  • js代碼執(zhí)行前,會(huì)有一個(gè)預(yù)編譯過(guò)程,該過(guò)程主要進(jìn)行以下操作:語(yǔ)法檢查,和聲明提升。 聲明提升,又分為兩部分:變量聲...
    DaZzling_佳閱讀 216評(píng)論 0 0
  • 《ijs》速成開(kāi)發(fā)手冊(cè)3.0 官方用戶交流:iApp開(kāi)發(fā)交流(1) 239547050iApp開(kāi)發(fā)交流(2) 10...
    葉染柒丶閱讀 5,342評(píng)論 0 7
  • 對(duì)于所有的變量,無(wú)論在函數(shù)體的何處進(jìn)行聲明,都會(huì)在后臺(tái)被提升到函數(shù)的頂部。 1.對(duì)于非函數(shù)變量 var str =...
    TingsLee閱讀 197評(píng)論 0 0
  • 來(lái)源:仗劍走天涯! 關(guān)于javascript的作用域的一些總結(jié),主要參考以上文章,加上自己的整理的理解。 近日對(duì)j...
    Michael_林閱讀 964評(píng)論 0 1
  • 曾經(jīng)我夢(mèng)想像武俠小說(shuō)中的英雄一樣浪跡天涯,曾經(jīng)我渴望一夜暴富,從此不再為錢而煩惱,曾經(jīng)我被最好的朋友欺騙,曾經(jīng)?當(dāng)...
    香水佬閱讀 286評(píng)論 0 1