JavaScript提升機(jī)制Hoisting的示例分析-創(chuàng)新互聯(lián)

這篇文章主要為大家展示了“JavaScript提升機(jī)制Hoisting的示例分析”,內(nèi)容簡(jiǎn)而易懂,條理清晰,希望能夠幫助大家解決疑惑,下面讓小編帶領(lǐng)大家一起研究并學(xué)習(xí)一下“JavaScript提升機(jī)制Hoisting的示例分析”這篇文章吧。

10余年的鎮(zhèn)坪網(wǎng)站建設(shè)經(jīng)驗(yàn),針對(duì)設(shè)計(jì)、前端、開(kāi)發(fā)、售后、文案、推廣等六對(duì)一服務(wù),響應(yīng)快,48小時(shí)及時(shí)工作處理。成都全網(wǎng)營(yíng)銷推廣的優(yōu)勢(shì)是能夠根據(jù)用戶設(shè)備顯示端的尺寸不同,自動(dòng)調(diào)整鎮(zhèn)坪建站的顯示方式,使網(wǎng)站能夠適用不同顯示終端,在瀏覽器中調(diào)整網(wǎng)站的寬度,無(wú)論在任何一種瀏覽器上瀏覽網(wǎng)站,都能展現(xiàn)優(yōu)雅布局與設(shè)計(jì),從而大程度地提升瀏覽體驗(yàn)。成都創(chuàng)新互聯(lián)公司從事“鎮(zhèn)坪網(wǎng)站設(shè)計(jì)”,“鎮(zhèn)坪網(wǎng)站推廣”以來(lái),每個(gè)客戶項(xiàng)目都認(rèn)真落實(shí)執(zhí)行。

前言

剛接觸到JavaScript的時(shí)候,便知道JavaScript是按順序執(zhí)行的,是如瀏覽器的解析DOM樹(shù)一樣的流程,解析DOM結(jié)構(gòu)的時(shí)候,如果遇到JS腳本或者外聯(lián)腳本便會(huì)停止解析,繼續(xù)下載腳本之后,執(zhí)行腳本,然后再解析DOM。

然而,卻因此常常碰到問(wèn)題。

看如下代碼以及輸出:

var name;
console.log(name);  // undefined
name = 'tom';

age = 10;
var age;
console.log(age); // 10

上面的代碼讓我們產(chǎn)生了疑惑,我們僅僅聲明了name的時(shí)候,打印出來(lái)值是undefined,按理說(shuō),重新聲明age之后,age的值應(yīng)該也是undefined才對(duì),但是輸出來(lái)的卻是10。這究竟是怎么回事兒呢?

我們的通用解釋是,遇到了變量提升。

而這樣的情況,我們?cè)诤瘮?shù)中也會(huì)看到,請(qǐng)看下面代碼:

log();
console.log(name);
var name = 'tom';
function log() {
  console.log('this is log');
}

上面代碼的輸出結(jié)果是什么?

輸出結(jié)果:

this is log
undefined

為什么會(huì)產(chǎn)生這樣的情形呢?我們通用的解釋是,函數(shù)聲明提升了。

而針對(duì)這兩種情況,就是我們經(jīng)常遇到的提升機(jī)制,也就是我們常說(shuō)的Hoisting。

而僅僅只是一句提升機(jī)制來(lái)解釋這種現(xiàn)象,還是覺(jué)得云里霧里,要是我之前可能也就不明覺(jué)厲的哦了一聲,然后就不再理會(huì)這樣的東西了,那么究竟為什么會(huì)出現(xiàn)這樣的情況呢?

JavaScript是如何被編譯的呢

有時(shí)候我們會(huì)想,一段JS代碼是如何執(zhí)行的呢?其實(shí),在JS代碼被執(zhí)行之前,通常都有一個(gè)編譯過(guò)程。

這個(gè)編譯過(guò)程其實(shí)很復(fù)雜,但總體來(lái)說(shuō),逃不過(guò)編譯過(guò)程的步驟,只不過(guò)JavaScript是在這個(gè)步驟之中對(duì)代碼做了優(yōu)化處理。

第一、詞法分析

詞法分析主要是將一段程序分解成有意義的代碼塊,便于對(duì)分解的代碼塊做解析。

比如,var age = 10;這一段代碼將會(huì)被分解成 var、age、=、10、;。這是5個(gè)詞法單元。

這些單元分析完畢之后,便會(huì)給解析器調(diào)用,生成相應(yīng)的AST(抽象語(yǔ)法樹(shù))。

第二、解析詞法單元

解析詞法單元,是為了生成AST,那么到底什么是AST呢,我們來(lái)看一段代碼以及解析生成的AST。

JavaScript提升機(jī)制Hoisting的示例分析

同樣是var age = 10;這段代碼,被解析器解析成了一段樹(shù)形結(jié)構(gòu)的結(jié)構(gòu),這個(gè)結(jié)構(gòu),就是抽象語(yǔ)法樹(shù)AST。你可以通過(guò)這個(gè)網(wǎng)站來(lái)查看生產(chǎn)的AST:AST解析器

而抽象語(yǔ)法樹(shù),又是可以轉(zhuǎn)換成可執(zhí)行代碼。這就涉及到編譯的第三個(gè)階段。

第三、生成可執(zhí)行代碼

生成可執(zhí)行代碼的過(guò)程,相當(dāng)于是再把AST轉(zhuǎn)換成瀏覽器可執(zhí)行的代碼,或者是各種語(yǔ)言引擎可執(zhí)行的代碼。

比如我們常見(jiàn)的babel,可以讓我們用ES6的語(yǔ)法去開(kāi)發(fā)程序,其實(shí)就是依靠babel編譯器,將我們的ES6代碼編譯成ES6的AST,然后將ES6的AST轉(zhuǎn)換成ES5的AST或者ES3的AST,最后將AST轉(zhuǎn)成ES5或ES3的代碼來(lái)讓瀏覽器執(zhí)行。

同理,TypeScript的TSC也是一個(gè)編譯器,做的事情和babel是一樣的,只不過(guò)兩者編譯出來(lái)的ES6的AST有略微的差別,這樣就造成了TypeScript用不了Babel社區(qū)的豐富多樣的插件,如eslint等。

因?yàn)閑slint語(yǔ)法檢查,正是基于AST做的。

那么上面這個(gè)編譯過(guò)程有什么用呢?

JavaScript中的聲明和賦值

理解了語(yǔ)言的編譯過(guò)程,那么JavaScript中的聲明和賦值又是如何的一個(gè)流程呢?

比如,var age = 10;這段代碼,在JavaScript中的編譯方式是如何呢?

在JavaScript中,這段代碼大概相當(dāng)于是如下兩個(gè)過(guò)程:

var age = undefined;   // 隱式賦值,編譯階段
age = 10;  //變量賦值  執(zhí)行階段

函數(shù)聲明也是如此:

// 這一段代碼就是一個(gè)完整的函數(shù)聲明,在編譯階段中,會(huì)先執(zhí)行所有聲明,才會(huì)依次執(zhí)行代碼操作。
function log() {
  console.log('this is log')
}

這個(gè)時(shí)候,我們?cè)倩仡^來(lái),想一下提升機(jī)制是什么?

再看提升

JavaScript的執(zhí)行,被分為了兩個(gè)階段,分別是編譯階段,以及執(zhí)行階段。依照這個(gè)來(lái)看,所謂的提升機(jī)制(有的叫做變量提升,考慮到函數(shù)的定義,并未用這個(gè)名詞),就是JavaScript引擎把變量聲明和函數(shù)聲明在編譯階段首先進(jìn)行默認(rèn)賦值,之后,在程序執(zhí)行階段,才會(huì)被代碼真正的執(zhí)行。也就是說(shuō),針對(duì)聲明先提升,后執(zhí)行。

注意:函數(shù)聲明和變量都有提升機(jī)制,兩者之間也有優(yōu)先級(jí)。這都遵循一個(gè)原則:函數(shù)優(yōu)先原則。也就是說(shuō),函數(shù)聲明會(huì)提升到普通變量聲明之前。

以上是“JavaScript提升機(jī)制Hoisting的示例分析”這篇文章的所有內(nèi)容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內(nèi)容對(duì)大家有所幫助,如果還想學(xué)習(xí)更多知識(shí),歡迎關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道!

文章名稱:JavaScript提升機(jī)制Hoisting的示例分析-創(chuàng)新互聯(lián)
轉(zhuǎn)載源于:http://muchs.cn/article16/dsihdg.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供云服務(wù)器、網(wǎng)站改版、網(wǎng)站制作商城網(wǎng)站、自適應(yīng)網(wǎng)站、虛擬主機(jī)

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)

網(wǎng)站托管運(yùn)營(yíng)