扒一扒JavaScript 預(yù)解釋
帶var關(guān)鍵字預(yù)解釋
讓我們先看下這段代碼執(zhí)行的結(jié)果:
alert(n);//彈出undefined
var n = 10;
彈出的結(jié)果是undefined,為何不是10?讓我們?cè)倏聪旅孢@段代碼執(zhí)行的結(jié)果:
alert(n);
n = 10;
運(yùn)行報(bào)如下錯(cuò)誤:

為何這次會(huì)報(bào)錯(cuò),原因是代碼在運(yùn)行的時(shí)候,沒(méi)有聲明這個(gè)變量n;通過(guò)這兩段代碼的比較,我們發(fā)現(xiàn)帶var關(guān)鍵字和不帶var關(guān)鍵字聲明的變量是有區(qū)別的,帶var聲明的變量在代碼執(zhí)行之前,似乎瀏覽器已經(jīng)給了它們一個(gè)初始值undefined,因此我們將代碼執(zhí)行前,瀏覽器引擎自動(dòng)掃描帶var關(guān)鍵字和帶function關(guān)鍵字(后面會(huì)提到)聲明的變量和定義的函數(shù)的這個(gè)過(guò)程稱(chēng)為預(yù)解釋。
帶function關(guān)鍵字預(yù)解釋
讓我們看下如下代碼執(zhí)行的結(jié)果:
fn();//彈出hello
function fn(){
alert('hello');
}
執(zhí)行結(jié)果彈出hello,fn能夠正常執(zhí)行,原因是在代碼執(zhí)行前fn被預(yù)解釋了,在預(yù)解釋時(shí)已經(jīng)將fn定義(defined)了,我們又有疑問(wèn)了,為何第一段代碼執(zhí)行結(jié)果不彈出10,而是undefined,再次引入了另一個(gè)概念JavaScript中的聲明和定義。
JavaScript中的聲明(declare)和定義(defined)
我們通常用var關(guān)鍵來(lái)聲明變量,用function關(guān)鍵字來(lái)定義函數(shù),只不過(guò)function關(guān)鍵字聲明和定義函數(shù)是同時(shí)執(zhí)行的,而var它只能聲明變量,并不具備定義的功能。
如下是用var關(guān)鍵字聲明的變量:
var n;//聲明了一個(gè)變量n
var m = 10;//聲明了一個(gè)變量m,并且將10賦值給它
如下是用function關(guān)鍵字定義的函數(shù):
//定義了一個(gè)函數(shù)fn
function fn(){
alert('hello');
}
帶var關(guān)鍵字和帶function關(guān)鍵字預(yù)解釋的區(qū)別
其實(shí)它倆的區(qū)別就是帶var關(guān)鍵字預(yù)解釋時(shí)只預(yù)解釋聲明部分(因?yàn)樗旧聿痪邆涠x的能力),而帶function關(guān)鍵字在預(yù)解釋時(shí)聲明和定義同時(shí)被預(yù)解釋。這時(shí)我們?cè)倩仡^分析下第一段代碼,分析如下:

無(wú)節(jié)操(坑爹)的預(yù)解釋
為何說(shuō)它無(wú)節(jié)操,請(qǐng)看下面的代碼(火狐除外):
alert(n);
fn();
if(false) {
var n = 10;
function fn(){
alert('hello');
}
}
第一行代碼執(zhí)行會(huì)彈出undefined,第二行代碼執(zhí)行會(huì)彈出hello;是因?yàn)閚和fn在代碼執(zhí)行前被預(yù)解釋了,即使if條件判斷為false,執(zhí)著的瀏覽器引擎也會(huì)將帶var關(guān)鍵字聲明的變量n和帶function關(guān)鍵定義的fn掃描到。
*預(yù)解釋忽略重新聲明,不忽略重新定義
這個(gè)地方因?yàn)橄鄬?duì)比較繞而且不太好理解,所以加了一個(gè)星號(hào),請(qǐng)看如下代碼:
alert(n);
var n = 10;
var n = 9;
var n;
alert(n);
這段代碼執(zhí)行結(jié)果是什么,我們來(lái)分析一下:

繼續(xù)上代碼,請(qǐng)分析如下執(zhí)行結(jié)果:
fn();
function fn() {
alert('1');
}
fn();
function fn() {
alert('2');
}
fn();
代碼分析圖如下:

帶function定義的函數(shù)預(yù)解釋分析
總結(jié):
本篇博文用了大篇幅代碼和截圖對(duì)JavaScript中預(yù)解釋作了概述,縱觀各種書(shū)籍對(duì)預(yù)解釋的描述甚少,其實(shí)平時(shí)在工作中使用的場(chǎng)景也并不多,遺憾的是預(yù)解釋是各大公司面試題必考。在剛開(kāi)始接觸它的時(shí)候,感覺(jué)它總是不按照常理寫(xiě)代碼,但是有些時(shí)候卻能夠正常運(yùn)行并不會(huì)報(bào)錯(cuò),當(dāng)然這也增加了我們對(duì)它神秘感的探索,也讓我們進(jìn)一步了解瀏覽器引擎是怎么解釋執(zhí)行我們的代碼。特此在后面的博文中我會(huì)拿幾道經(jīng)典的案例來(lái)綜合分析它,再次感謝大家的支持!
相關(guān)文章
JS promise解決異步問(wèn)題過(guò)程詳解
Promise是異步編程的一種解決方案,比傳統(tǒng)的解決方案——回調(diào)函數(shù)和事件——更合理和更強(qiáng)大。簡(jiǎn)單說(shuō)就是一個(gè)容器,里面保存著某個(gè)未來(lái)才會(huì)結(jié)束的事件(通常是一個(gè)異步操作)的結(jié)果。從語(yǔ)法上說(shuō),Promise是一個(gè)對(duì)象,從它可以獲取異步操作的消息2023-04-04
JavaScript中數(shù)組嵌套對(duì)象排序方法的示例詳解
在?JavaScript?中,可以使用?sort()?方法對(duì)包含嵌套對(duì)象的數(shù)組進(jìn)行排序,本文將通過(guò)三個(gè)簡(jiǎn)單的示例為大家進(jìn)行簡(jiǎn)單的介紹,需要的可以參考下2024-03-03
基于JS實(shí)現(xiàn)發(fā)送驗(yàn)證碼的計(jì)時(shí)器效果
這篇文章主要為大家詳細(xì)介紹了如何基于JS實(shí)現(xiàn)一個(gè)發(fā)送驗(yàn)證碼的計(jì)時(shí)器效果,文中的示例代碼講解詳細(xì),感興趣的小伙伴快跟隨小編一起學(xué)習(xí)一下吧2023-11-11
JS將時(shí)間秒轉(zhuǎn)換成天小時(shí)分鐘秒的字符串
最近小編接到這樣的項(xiàng)目需求,接口返回的數(shù)據(jù)中時(shí)間單位為秒,但前端顯示的時(shí)候需要更人性化的帶有單位(天,小時(shí),分鐘,秒)的字符串;下面小編給大家?guī)?lái)實(shí)例代碼,感興趣的朋友跟隨小編一起看看吧2019-07-07
javascript實(shí)現(xiàn)輸出指定行數(shù)正方形圖案的方法
這篇文章主要介紹了javascript實(shí)現(xiàn)輸出指定行數(shù)正方形圖案的方法,可實(shí)現(xiàn)javascript獲取用戶(hù)輸入及根據(jù)輸入?yún)?shù)打印圖形的功能,需要的朋友可以參考下2015-08-08
javascript深拷貝的原理與實(shí)現(xiàn)方法分析
這篇文章主要介紹了javascript深拷貝的原理與實(shí)現(xiàn)方法,簡(jiǎn)單分析了值傳遞和引用傳遞的原理與實(shí)現(xiàn)方法,并結(jié)合實(shí)例形式給出了深拷貝的具體實(shí)現(xiàn)技巧,需要的朋友可以參考下2017-04-04

