成人无码视频,亚洲精品久久久久av无码,午夜精品久久久久久毛片,亚洲 中文字幕 日韩 无码

資訊專欄INFORMATION COLUMN

JavaScript到底是解釋型語(yǔ)言還是編譯型語(yǔ)言?

gghyoo / 2400人閱讀

摘要:編譯型語(yǔ)言解釋型語(yǔ)言主要問題是沒有團(tuán)體或者組織規(guī)定這些例如編譯型語(yǔ)言和解釋型語(yǔ)言的定義以及如何劃分。下面是處理聲明語(yǔ)句的過程一旦引擎進(jìn)入一個(gè)執(zhí)行具體代碼的執(zhí)行上下文函數(shù),它就對(duì)代碼進(jìn)行詞法分析或者分詞。這是解釋型語(yǔ)言需要的。

幾天前一個(gè)剛接觸 JavaScript 的朋友問我 JavaScript 是編譯型語(yǔ)言還是解釋型語(yǔ)言。從一個(gè)初學(xué)者那里聽到這樣的問題讓我有些驚訝,因?yàn)樗谐鯇W(xué)者都知道 JS 是一個(gè)解釋型語(yǔ)言;特別是像她這樣之前使用過 Java 這類語(yǔ)言的初學(xué)者。

當(dāng)一些人深入 JavaScript 并且開始研究 V8 引擎、SpiderMonkey、JIT 之類東西的時(shí)候,他們開始對(duì)于解釋型還是編譯型有更多的疑問。很高興看到她已經(jīng)在這個(gè)階段了。

令人困惑的是什么?

最開始的時(shí)候,JavaScript 的圣經(jīng) —— MDN 明確地說 JavaScript 是一個(gè)解釋型語(yǔ)言(同時(shí)還說到了 JIT 及時(shí)編譯,后文會(huì)提及)。但是下面幾點(diǎn)仍然會(huì)讓 JavaScript 是否真的是一個(gè)解釋型語(yǔ)言產(chǎn)生疑問:

如果 JS 是解釋型語(yǔ)言那為什么會(huì)有變量提升(hoisting)?

JIT(及時(shí)編譯)會(huì)做代碼優(yōu)化(同時(shí)創(chuàng)建代碼的編譯版本);解釋型語(yǔ)言無法做到這些。

有什么快速的回答嗎?

由于 JavaScript 規(guī)范沒有對(duì)這一點(diǎn)做明確說明,困惑和疑問是都是存在的,不能片面地回答。讓我們基于理論定義和 JavaScript 工作流程來弄清楚 JavaScript 到底是什么語(yǔ)言。

編譯型語(yǔ)言 VS 解釋型語(yǔ)言

主要問題是沒有團(tuán)體或者組織規(guī)定這些;例如:編譯型語(yǔ)言和解釋型語(yǔ)言的定義以及如何劃分。 而這兩個(gè)都是概念。

所以根據(jù)概念,編譯型語(yǔ)言是代碼在運(yùn)行前編譯器將人類可以理解的語(yǔ)言(編程語(yǔ)言)轉(zhuǎn)換成機(jī)器可以理解的語(yǔ)言。

解釋型語(yǔ)言也是人類可以理解的語(yǔ)言(編程語(yǔ)言),也需要轉(zhuǎn)換成機(jī)器可以理解的語(yǔ)言才能執(zhí)行,但是是在運(yùn)行時(shí)轉(zhuǎn)換的。所以執(zhí)行前需要環(huán)境中安裝了解釋器;但是編譯型語(yǔ)言編寫的應(yīng)用在編譯后能直接運(yùn)行。

許多人認(rèn)為解釋型語(yǔ)言意味著當(dāng)遇到程序中行號(hào)為xyz時(shí)直接將其傳給CPU就能運(yùn)行;但是事實(shí)不是這樣。所有的編程語(yǔ)言都是為人類創(chuàng)建的。他們是人類能夠理解的。必須將編程語(yǔ)言轉(zhuǎn)換為機(jī)器語(yǔ)言才能運(yùn)行。編譯器獲取整個(gè)代碼,轉(zhuǎn)換它,做合適的優(yōu)化并且創(chuàng)建一個(gè)可以運(yùn)行的輸出文件。編譯器根據(jù)上下文來轉(zhuǎn)換語(yǔ)句。

那么變量提升呢?

我覺得你應(yīng)該已經(jīng)知道了 JavaScript 的變量提升。在函數(shù)作用域內(nèi)的任何變量的聲明都會(huì)被提升到頂部并且值為undeinfed。

所以 JavaScript 引擎好像解釋了同一個(gè)腳本文件兩次?第一次完成所有的聲明提升然后第二次才執(zhí)行代碼?還是先編譯整個(gè)代碼然后運(yùn)行它?這兩種都不對(duì)。

下面是 JavaScript 處理聲明語(yǔ)句的過程:

一旦 V8 引擎進(jìn)入一個(gè)執(zhí)行具體代碼的執(zhí)行上下文(函數(shù)),它就對(duì)代碼進(jìn)行詞法分析或者分詞。這意味著代碼將被分割成像foo = 10這樣的原子符號(hào)(atomic token)。

在對(duì)當(dāng)前的整個(gè)作用域分析完成后,引擎將 token 解析翻譯成一個(gè)AST(抽象語(yǔ)法樹)。

引擎每次遇到聲明語(yǔ)句,就會(huì)把聲明傳到作用域(scope)中創(chuàng)建一個(gè)綁定。每次聲明都會(huì)為變量分配內(nèi)存。只是分配內(nèi)存,并不會(huì)修改源代碼將變量聲明語(yǔ)句提升。正如你所知道的,在JS中分配內(nèi)存意味著將變量默認(rèn)設(shè)為undefined。

在這之后,引擎每一次遇到賦值或者取值,都會(huì)通過作用域(scope)查找綁定。如果在當(dāng)前作用域中沒有查找到就接著向上級(jí)作用域查找直到找到為止。

接著引擎生成 CPU 可以執(zhí)行的機(jī)器碼。

最后, 代碼執(zhí)行完畢。

所以變量提升不過是執(zhí)行上下文的小把戲,而不是許多網(wǎng)站描述的源代碼修改。在執(zhí)行任何語(yǔ)句之前,解釋器就要從創(chuàng)建執(zhí)行上下文后已經(jīng)存在的作用域(scope)中找到變量的值。

解釋 JavaScript 中的即時(shí)編譯(JIT)

JIT 或 及時(shí)編譯 編譯器不是 JavaScript 所特有的。其他語(yǔ)言比如 Java 也有一些在執(zhí)行前編譯代碼的機(jī)制。

現(xiàn)代 JavaScript 引擎同樣有 JIT。是的,它們有編譯器。讓我來為你解釋一下為什么它們需要 JIT 以及 JIT 在 JavaScript 的執(zhí)行中是如何工作的。

編譯型和解釋型語(yǔ)言最重要的區(qū)別是編譯型語(yǔ)言需要很長(zhǎng)的時(shí)間來準(zhǔn)備執(zhí)行。因?yàn)樗枰獙?duì)整個(gè)代碼進(jìn)行詞法分析、做一些極致的優(yōu)化等工作。另一方面解釋型語(yǔ)言幾乎在執(zhí)行后一瞬間就開始,但是沒有任何代碼優(yōu)化。所以每一條語(yǔ)句都是分開轉(zhuǎn)換(編譯)的,考慮下面這一段代碼。

for(i=0; i < 1000; i++){
    sum += i;
}

在編譯型語(yǔ)言中sum += i部分在循環(huán)運(yùn)行時(shí)已經(jīng)編譯成了機(jī)器碼,機(jī)器碼將直接運(yùn)行一千次。

但是在解釋型語(yǔ)言中,執(zhí)行時(shí)會(huì)將sum += i轉(zhuǎn)換(編譯)一千次。對(duì)相同的代碼進(jìn)行一千次轉(zhuǎn)換會(huì)造成非常大的性能損耗。

這就是 Google 和 Mozilla 的開發(fā)人員將 JIT 加入 JavaScript 的原因。

編譯

在 JavaScript 中如果一段代碼運(yùn)行超過一次,那么就稱為 warm。如果一個(gè)函數(shù)開始變得 warmer(譯者注:即運(yùn)行更多次),JIT 將把這段代碼送到編譯器中編譯并且保存一個(gè)編譯后的版本。下一次同樣代碼執(zhí)行的時(shí)候,引擎會(huì)跳過翻譯過程直接使用編譯后的版本。

這將優(yōu)化性能。在真正的編譯器中,因?yàn)榫幾g器能訪問整個(gè)代碼所以做了除此之外更多的事情。

優(yōu)化

如果一段 warm 的代碼變得 hot 或者 hotter(譯者注:指運(yùn)行更多次以及比更多還要多的次數(shù))JIT 會(huì)嘗試更多的優(yōu)化并且保存優(yōu)化后的版本。在編譯器進(jìn)行優(yōu)化的過程中會(huì)做一些關(guān)于變量類型和運(yùn)行環(huán)境中值的假設(shè),如果假設(shè)不成立就將這個(gè)優(yōu)化的版本回退,如果假設(shè)成立的話,這將讓代碼性能更高。

想要了解更多 JIT 的知識(shí)可以閱讀 Lin Clarks 關(guān)于JIT的課程。

總結(jié)

現(xiàn)在我們了解了 JavaScript 執(zhí)行時(shí)到底發(fā)生了什么,所以應(yīng)該可以區(qū)分 JavaScript 到底是編譯型還是解釋型語(yǔ)言了。下面是這篇文章的要點(diǎn)。

JavaScript 代碼需要在機(jī)器(node 或者瀏覽器)上安裝一個(gè)工具(JS 引擎)才能執(zhí)行。這是解釋型語(yǔ)言需要的。編譯型語(yǔ)言程序能夠自由地直接運(yùn)行。

變量提升不是代碼修改。在這個(gè)過程中沒有生成中間代碼。變量提升只是 JS 解釋器處理事情的方式。

JIT 是唯一一點(diǎn)我們可以對(duì) JavaScript 是否是一個(gè)解釋型語(yǔ)言提出疑問的理由。但是 JIT 不是完整的編譯器,它在執(zhí)行前進(jìn)行編譯。而且 JIT 只是 Mozilla 和 Google 的開發(fā)人員為了提升瀏覽器性能才引入的。JavaScript 或 TC39 從來沒有強(qiáng)制要求使用 JIT。

因此,雖然 JavaScript 執(zhí)行時(shí)像是在編譯或者像是一種編譯和解釋的混合,我仍然認(rèn)為 JavaScript 是一個(gè)解釋型語(yǔ)言或者是一個(gè)今天很多人說的混合型語(yǔ)言,而不是編譯型語(yǔ)言。

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://m.hztianpu.com/yun/107210.html

相關(guān)文章

  • Java到底編譯語(yǔ)言解釋語(yǔ)言?

    摘要:編譯型語(yǔ)言把做好的源程序全部編譯成二進(jìn)制代碼的可運(yùn)行程序。所以可是說即是編譯型的,也是解釋型,但是假如非要?dú)w類的話,從概念上的定義,恐怕應(yīng)該歸到解釋型的語(yǔ)言中。編譯型的語(yǔ)言包括解釋型的語(yǔ)言包括 轉(zhuǎn)載自網(wǎng)絡(luò) Java這個(gè)語(yǔ)言很神奇: 你可以說它是編譯型的。因?yàn)樗械腏ava代碼都是要編譯的,.java不經(jīng)過編譯就什么用都沒有。 你可以說它是解釋型的。因?yàn)閖ava代碼編譯后不能直接運(yùn)行,...

    KavenFan 評(píng)論0 收藏0
  • JAVA到底編譯語(yǔ)言解釋語(yǔ)言?

    摘要:最后給出編譯型語(yǔ)言和解釋型語(yǔ)言的定義。定義編譯型語(yǔ)言把做好的源程序全部編譯成二進(jìn)制代碼的可運(yùn)行程序。解釋型語(yǔ)言把做好的源程序翻譯一句,然后執(zhí)行一句,直至結(jié)束特點(diǎn)編譯型語(yǔ)言,執(zhí)行速度快效率高依靠編譯器跨平臺(tái)性差。 有人說Java是編譯型的。因?yàn)樗械腏ava代碼都是要編譯的,.java不經(jīng)過編譯就無法執(zhí)行。 也有人說Java是解釋型的。因?yàn)閖ava代碼編譯后不能直接運(yùn)行,它是解釋運(yùn)行在J...

    beanlam 評(píng)論0 收藏0
  • Python的發(fā)展歷程

    摘要:可以脫離語(yǔ)言環(huán)境獨(dú)立運(yùn)行就像一本英文書,我找一個(gè)翻譯,給他點(diǎn)時(shí)間,把英文書翻譯成中文的,這就是編譯型語(yǔ)言解釋型語(yǔ)言有良好的平臺(tái)兼容性,在任何環(huán)境中都可以運(yùn)行,前提是安裝了解釋器虛擬機(jī)。就像還是一本英文書,我看一句讓他給我解釋一句。 寫在前面 隨著大數(shù)據(jù)、人工智能這類詞匯撲向我們,python這個(gè)早在1989就已經(jīng)出現(xiàn)的語(yǔ)言終于高調(diào)回歸,為了更好的學(xué)習(xí)python 我們先來了解下它的前世...

    lovXin 評(píng)論0 收藏0
  • JavaScript編程全解 —— 基礎(chǔ)

    摘要:函數(shù)式編程最后介紹一下函數(shù)式編程。函數(shù)式編程是一種歷史悠久,而又在最近頗為熱門的話題。函數(shù)式編程在面向?qū)ο笠辉~誕生以前就已經(jīng)存在,不過它在很長(zhǎng)一段時(shí)間里都被隱藏于過程式編程面向?qū)ο笠彩沁^程式編程的一種的概念之下。 2.1 JavaScript特點(diǎn) 總結(jié)以下幾個(gè)特點(diǎn): 解釋型語(yǔ)言 類似與C和Java的語(yǔ)法結(jié)構(gòu) 動(dòng)態(tài)語(yǔ)言 基于原型的面向?qū)ο?字面量的表現(xiàn)能力 函數(shù)式編程 解釋型語(yǔ)言:...

    CoreDump 評(píng)論0 收藏0
  • 做一個(gè)好前端必須要知道的事——JS語(yǔ)言

    摘要:準(zhǔn)確的理解,是編譯型語(yǔ)言,源代碼整個(gè)編譯成字節(jié)碼,字節(jié)碼,是解釋型語(yǔ)言。是一個(gè)非常靈活的語(yǔ)言,支持命令式和函數(shù)式編程。編譯型語(yǔ)言通常會(huì)用做配置文件,因?yàn)槲覀兺ǔ2粫?huì)改編譯后的字節(jié)碼。 編程語(yǔ)言按各種方法可以分為各種類型,現(xiàn)在讓我們來看看JS屬于什么類型語(yǔ)言 解釋型語(yǔ)言 按編譯執(zhí)行過程,可以分為編譯型語(yǔ)言和解釋型語(yǔ)言。比如 c 語(yǔ)言,必須先經(jīng)過編譯生成目標(biāo)文件,然后鏈接各個(gè)目標(biāo)文件和庫(kù)...

    Near_Li 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

gghyoo

|高級(jí)講師

TA的文章

閱讀更多
最新活動(dòng)
閱讀需要支付1元查看
<