JAVAScript(簡稱js)廣泛應(yīng)用在web開發(fā)領(lǐng)域,幾乎是web開發(fā)的唯一編程語言,近些年,借助node.js的快速發(fā)展,js在服務(wù)器領(lǐng)域也有了非常廣泛運(yùn)用與拓展。
然而,雖然js在前后端都有了一定的發(fā)展,很多js開發(fā)者也熟練使用大量的js代碼庫,但很多人依然理不清js的各種關(guān)鍵術(shù)語。
本文不講解具體開發(fā)技巧技術(shù),只講解其中的知識點(diǎn),幫助大家理解這些關(guān)鍵術(shù)語的內(nèi)涵。
ECMAScript
js前端面試,總繞不開的一個(gè)ES,所以這個(gè)ES到底是什么?
從名詞解釋上
ECMAScript是一種由Ecma國際通過ECMA-262標(biāo)準(zhǔn)化的腳本程序設(shè)計(jì)語言。
說是語言定義,ES更像是一套標(biāo)準(zhǔn)。而我們說的js則是ES的一個(gè)實(shí)現(xiàn)。歷史上有其他語言實(shí)現(xiàn)過ES標(biāo)準(zhǔn),比如運(yùn)行在flash上面的actionscript。
ES 并不等于js。
ES涵蓋了js幾乎所有語法層面的東西,記住語法這一點(diǎn),舉幾個(gè)例子
- 寫js幾乎都知道setTimeout/setInterval 這2個(gè)計(jì)時(shí)器函數(shù),然而,ES標(biāo)準(zhǔn)里面至今也沒有對這2個(gè)函數(shù)的定義說明。 這兩貨壓根就不被正統(tǒng)ES認(rèn)可。
- 一說到j(luò)s網(wǎng)絡(luò)請求,很多開發(fā)人員張口就來XHR和fetch,但是ES標(biāo)準(zhǔn)根本沒有網(wǎng)絡(luò)和http的任何定義。
那明明不是ES標(biāo)準(zhǔn),為何所有瀏覽器都實(shí)現(xiàn)了?
這就要牽扯到另一個(gè)標(biāo)準(zhǔn)委員會 —— W3C標(biāo)準(zhǔn)委員會。
至于node.js,為了保證絕大多數(shù)js庫在不修改的情況下移植到node環(huán)境(吸納js開發(fā)者),所以也內(nèi)部實(shí)現(xiàn)了這兩個(gè)計(jì)時(shí)器函數(shù),但是網(wǎng)絡(luò)庫則是靠另一套模塊來實(shí)現(xiàn)。
- 基于上個(gè)問題的延伸,ES6以后,JS開發(fā)者可能都思考過或者被問過JS的事件循環(huán)機(jī)制是什么?
事件循環(huán)
js事件循環(huán)是基于js單線程體系下的最優(yōu)設(shè)計(jì)(具體js事件循環(huán)原理以后我在單獨(dú)講解)。
ES6之前,js事件循環(huán)非常單調(diào),除了異步IO、網(wǎng)絡(luò)和計(jì)時(shí)器幾乎沒什么可以講的。ES6以后,事件循環(huán)里面有了2個(gè)概念:微任務(wù)隊(duì)列(MicrotaskQueue)和宏任務(wù)隊(duì)列(macroTaskQueue),如Promise的底層實(shí)現(xiàn)就離不開微任務(wù)隊(duì)列。ES標(biāo)準(zhǔn)想納入Promise協(xié)程,就必須把微任務(wù)隊(duì)列添加到標(biāo)準(zhǔn)里面。
我們也知道setTimeout/setInterval是跟宏任務(wù)隊(duì)列關(guān)聯(lián)。但是請切記,宏任務(wù)這個(gè)也不是ES的標(biāo)準(zhǔn)。
所有的js引擎都沒有提供宏任務(wù)隊(duì)列的任何API接口,如v8(Chrome和node.js背后的js引擎)、JSC(Safari瀏覽器js引擎)、SpiderMonkey等,你不可能在其中找到宏任務(wù)實(shí)現(xiàn)接口,宏任務(wù)隊(duì)列完全由引擎上層依據(jù)設(shè)計(jì)去制定。
比如在Chrome瀏覽器上,一次事件循環(huán)里面必須提供供渲染調(diào)度的接口,但在node.js里面,無需提供渲染。
事實(shí)上,瀏覽器和node.js對宏任務(wù)的實(shí)現(xiàn)原理有很大差異,node.js靠libuv庫去驅(qū)動(dòng)事件循環(huán)。
所以有人有疑問,既然不是標(biāo)準(zhǔn),那為什么所有瀏覽器和node的js執(zhí)行環(huán)境都提供了宏任務(wù)隊(duì)列?
這就回到上面的第一句:js事件循環(huán)是基于js單線程體系下的最優(yōu)設(shè)計(jì)。宏任務(wù)隊(duì)列是各家巨頭們約定俗成的不成文標(biāo)準(zhǔn),既不屬于ES也不屬于W3C。
W3C
嚴(yán)格意義上說,w3c并不定義或者規(guī)范JS標(biāo)準(zhǔn),它只負(fù)責(zé)制定web規(guī)范并要求各家瀏覽器實(shí)現(xiàn),如html5標(biāo)準(zhǔn)。
W3C討論的標(biāo)準(zhǔn)必須在js的基礎(chǔ)上才能制定。
如網(wǎng)絡(luò)請求fetch API,fetch返回Promise,這個(gè)就必須在ES6標(biāo)準(zhǔn)之后才能使用。
所以,我們可以這么說,ES則是一種標(biāo)準(zhǔn)沒法直接用,JS是基于ES標(biāo)準(zhǔn)實(shí)現(xiàn)的一種編程語言可以用但是需要宿主環(huán)境,而W3C標(biāo)準(zhǔn)則負(fù)責(zé)制定web標(biāo)準(zhǔn)規(guī)范,這個(gè)標(biāo)準(zhǔn)規(guī)范實(shí)現(xiàn)依賴js。這三者逐層具象。






