最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

JavaScript提升機制Hoisting詳解

 更新時間:2019年10月23日 14:21:15   作者:得閑讀書  
這篇文章主要介紹了JavaScript提升機制Hoisting詳解,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下

前言

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

然而,卻因此常常碰到問題。

看如下代碼以及輸出:

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

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

上面的代碼讓我們產生了疑惑,我們僅僅聲明了name的時候,打印出來值是undefined,按理說,重新聲明age之后,age的值應該也是undefined才對,但是輸出來的卻是10。這究竟是怎么回事兒呢?

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

而這樣的情況,我們在函數中也會看到,請看下面代碼:

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

上面代碼的輸出結果是什么?

輸出結果:

this is log
undefined

為什么會產生這樣的情形呢?我們通用的解釋是,函數聲明提升了。

而針對這兩種情況,就是我們經常遇到的提升機制,也就是我們常說的Hoisting。

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

JavaScript是如何被編譯的呢

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

這個編譯過程其實很復雜,但總體來說,逃不過編譯過程的步驟,只不過JavaScript是在這個步驟之中對代碼做了優(yōu)化處理。

第一、詞法分析

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

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

這些單元分析完畢之后,便會給解析器調用,生成相應的AST(抽象語法樹)。

第二、解析詞法單元

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

同樣是var age = 10;這段代碼,被解析器解析成了一段樹形結構的結構,這個結構,就是抽象語法樹AST。你可以通過這個網站來查看生產的AST:AST解析器

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

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

生成可執(zhí)行代碼的過程,相當于是再把AST轉換成瀏覽器可執(zhí)行的代碼,或者是各種語言引擎可執(zhí)行的代碼。

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

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

因為eslint語法檢查,正是基于AST做的。

那么上面這個編譯過程有什么用呢?

JavaScript中的聲明和賦值

理解了語言的編譯過程,那么JavaScript中的聲明和賦值又是如何的一個流程呢?

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

在JavaScript中,這段代碼大概相當于是如下兩個過程:

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

函數聲明也是如此:

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

這個時候,我們再回頭來,想一下提升機制是什么?

再看提升

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

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

總結

變量提升,是一個值得去探究的概念,只有理解了這個概念,我們理解JavaScript的執(zhí)行機制將會變得清晰明了起來。

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。

相關文章

  • 純js代碼制作的網頁時鐘特效【附實例】

    純js代碼制作的網頁時鐘特效【附實例】

    下面小編就為大家?guī)硪黄僯s代碼制作的網頁時鐘特效【附實例】。小編覺得聽錯的,現在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2016-03-03
  • 用js限制網頁只在微信瀏覽器中打開(或者只能手機端訪問)

    用js限制網頁只在微信瀏覽器中打開(或者只能手機端訪問)

    這篇文章主要介紹了用js限制網頁只在微信瀏覽器中打開,很多電影站也是這么限制的,原因你懂的,需要的朋友可以參考下
    2020-01-01
  • 基于javascript顯示當前時間以及倒計時功能

    基于javascript顯示當前時間以及倒計時功能

    這篇文章主要為大家詳細介紹了基于javascript顯示當前時間以及倒計時功能的相關資料,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2016-03-03
  • JS+CSS實現仿新浪微博搜索框的方法

    JS+CSS實現仿新浪微博搜索框的方法

    這篇文章主要介紹了JS+CSS實現仿新浪微博搜索框的方法,實例分析了javascript針對搜索框樣式的控制技巧,具有一定參考借鑒價值,需要的朋友可以參考下
    2015-02-02
  • ES6新特性之函數的擴展實例詳解

    ES6新特性之函數的擴展實例詳解

    這篇文章主要介紹了ES6新特性之函數的擴展,實例形式較為詳細的分析了ES6針對函數參數、運算符及相關新特性的擴展操作與注意事項,需要的朋友可以參考下
    2017-04-04
  • 前端圖片懶加載(lazyload)的實現方法(提高用戶體驗)

    前端圖片懶加載(lazyload)的實現方法(提高用戶體驗)

    圖片懶加載又稱圖片延時加載、惰性加載,即在用戶需要使用圖片的時候加載,這樣可以減少請求,節(jié)省帶寬,提高頁面加載速度,相對的,也能減少服務器壓力,下面通過本文給大家分享圖片懶加載lazyload的實現方法,感興趣的朋友一起看看吧
    2017-08-08
  • 小程序實現側邊欄切換

    小程序實現側邊欄切換

    這篇文章主要為大家詳細介紹了小程序實現側邊欄切換效果,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-07-07
  • javascript實現計算器功能

    javascript實現計算器功能

    這篇文章主要為大家詳細介紹了javascript實現計算器功能,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2020-03-03
  • Bootstrap CSS組件之按鈕下拉菜單

    Bootstrap CSS組件之按鈕下拉菜單

    這篇文章主要為大家詳細介紹了Bootstrap CSS組件之按鈕下拉菜單,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2016-12-12
  • JavaScript判斷手機號運營商是移動、聯(lián)通、電信還是其他(代碼簡單)

    JavaScript判斷手機號運營商是移動、聯(lián)通、電信還是其他(代碼簡單)

    本文由腳本之家小編給大家分享的基于js判斷手機號運行商是移動、聯(lián)通、電信還是其他的,然后根據不同的運營商做出對應的處理,感興趣的朋友一起學習吧
    2015-09-09

最新評論

汉川市| 万盛区| 尼木县| 武邑县| 乡城县| 涪陵区| 龙口市| 锦州市| 客服| 吴旗县| 察雅县| 富民县| 宜昌市| 永德县| 德安县| 历史| 永顺县| 龙南县| 科技| 武乡县| 忻城县| 临颍县| 东乌| 哈巴河县| 土默特右旗| 潜山县| 博湖县| 炎陵县| 陵水| 个旧市| 新巴尔虎右旗| 清涧县| 依兰县| 高青县| 桑日县| 沽源县| 普兰县| 稷山县| 大安市| 海阳市| 慈利县|