新聞中心
大家好,我卡頌。

讓客戶滿意是我們工作的目標(biāo),不斷超越客戶的期望值來(lái)自于我們對(duì)這個(gè)行業(yè)的熱愛(ài)。我們立志把好的技術(shù)通過(guò)有效、簡(jiǎn)單的方式提供給客戶,將通過(guò)不懈努力成為客戶在信息化領(lǐng)域值得信任、有價(jià)值的長(zhǎng)期合作伙伴,公司提供的服務(wù)項(xiàng)目有:空間域名、網(wǎng)站空間、營(yíng)銷軟件、網(wǎng)站建設(shè)、措勤網(wǎng)站維護(hù)、網(wǎng)站推廣。
在布達(dá)佩斯2022 JSConf[1]會(huì)議上,tc39[2](ES標(biāo)準(zhǔn)委員會(huì))成員「Gil Tayar」介紹了一份當(dāng)前仍處于stage 1?階段的提案 —— Type Annotations?,意在讓原生JS支持類型注解。
Gil Tayar
換句話說(shuō),如果提案通過(guò),很多.ts?文件將后綴改為.js后就能直接在瀏覽器中運(yùn)行。
一份tc39提案通常會(huì)經(jīng)歷5個(gè)階段:
- stage 0:被提出。
- stage 1:接受審議。
- stage 2:規(guī)范基本完成。
- stage 3:等待被實(shí)現(xiàn)。
- stage 4:納入語(yǔ)言標(biāo)準(zhǔn)中。
所以Type Annotations當(dāng)前仍處于「接受審議」的狀態(tài)。
但是提案發(fā)起者「Gil Tayar」對(duì)這份提案的通過(guò)很有信心,本文我們來(lái)聊聊這份提案的相關(guān)內(nèi)容。
為什么需要原生類型注解?
根據(jù)20年、21年state of JS[3]的統(tǒng)計(jì),「靜態(tài)類型」高票當(dāng)選「JS中當(dāng)前最欠缺的功能」。
同時(shí),在Github報(bào)告[4]中,TS被列為「第四大最常用的語(yǔ)言」
所以,對(duì)前端工程師來(lái)說(shuō),「類型注解」需求很大。
那么,既然已經(jīng)有了TS?,為什么還需要原生JS支持「類型注解」呢?
通常來(lái)說(shuō),從「開(kāi)發(fā)者編寫的源代碼」到「線上生產(chǎn)環(huán)境代碼」間需要經(jīng)過(guò)「代碼編譯」。
「代碼編譯」主要包括兩個(gè)步驟:
- 降級(jí)編譯(包括高級(jí)語(yǔ)法轉(zhuǎn)換為低級(jí)語(yǔ)法,高級(jí)方法的polyfill)。
- 代碼轉(zhuǎn)譯(比如壓縮、混淆、tree-shaking、類型擦除)。
所謂「類型擦除」,是指擦除代碼中的「類型注解」,讓其變成符合原生JS規(guī)范的代碼,比如:
// 擦除前
function add(a: number, b: number): number {
return a + b;
}
// 擦除后
function add(a, b) {
return a + b;
}
隨著時(shí)間的推移,各主流瀏覽器兼容性越來(lái)越好,「步驟1」在可預(yù)見(jiàn)的未來(lái)重要性會(huì)逐漸降低。
對(duì)于TS開(kāi)發(fā)者,從「源代碼」到「線上生產(chǎn)環(huán)境代碼」間可能只需要「類型擦除」。
如果原生JS支持「類型注解」,就能省去「類型擦除」對(duì)應(yīng)的編譯流程,讓代碼更容易在宿主環(huán)境執(zhí)行。
和TS的關(guān)系
這份提案的目的,并不是另起爐灶,獨(dú)立實(shí)現(xiàn)一套原生??JS??的類型注解。而是與「TS團(tuán)隊(duì)」合作,提出一套合適的規(guī)范。
新的規(guī)范與「TS規(guī)范」的關(guān)系類似下圖:
一方面,Type Annotations?提案從TS中借鑒了很多特性,這就是圖中相交的部分。
你可以到grammar-conventions[5]看到規(guī)范當(dāng)前定義的類型
另一方面,TS?迭代速度很快,新的特性產(chǎn)出很快。而Type Annotations?作為JS?語(yǔ)言的一部分,迭代會(huì)更加保守,所以TS?中一些特性在Type Annotations中并不支持。
此外,TS?中一些結(jié)構(gòu)(比如Enums?、Namespaces?)存在運(yùn)行時(shí)的語(yǔ)義,Type Annotations也不會(huì)支持。
這些就是TS?中存在,而Type Annotations中不存在的部分。
最后,Type Annotations?設(shè)計(jì)的初衷并不是與TS?強(qiáng)綁定,而僅僅是提供一套類型規(guī)范,開(kāi)發(fā)者編寫代碼時(shí)的「類型檢查」還是由各種類型檢查器(比如TS?、Flow)實(shí)現(xiàn)。
所以,Type Annotations?還有一部分特性是TS?當(dāng)前未定義的,這也是為了規(guī)范更廣泛的適用性考慮的,也就是圖中Type Annotations?存在,而TS不存在的部分。
這部分特性需要TS?后續(xù)實(shí)現(xiàn),這也是為什么Type Annotations?要與TS團(tuán)隊(duì)合作的一大原因。
對(duì)開(kāi)發(fā)者意味著什么
如果Type Annotations最終出現(xiàn)在ES20xx版中,屆時(shí)開(kāi)發(fā)者編寫代碼的步驟是:
- 選擇合適的類型檢查器(比如TS),這個(gè)類型檢查器需要完全遵循Type Annotations規(guī)范(而不是自己的規(guī)范,比如TS規(guī)范)。
- 編寫帶類型聲明的原生JS代碼。
- 類型檢查器會(huì)檢查類型錯(cuò)誤,并給予報(bào)錯(cuò)或提示。
對(duì)于如下原生JS代碼,如果開(kāi)發(fā)者傳入了錯(cuò)誤的類型,JS會(huì)報(bào)錯(cuò)么?
function add(a: number, b: number): number {
return a + b;
}
// 錯(cuò)誤的類型傳參
add('KaSong', 123);答案是:不會(huì)。
Type Annotations僅僅是一套規(guī)范,該規(guī)范由各種類型檢查器執(zhí)行。
JS的宿主環(huán)境(比如瀏覽器)在執(zhí)行「帶類型聲明的JS代碼」時(shí),會(huì)忽略類型聲明。
總結(jié)
有同學(xué)可能會(huì)問(wèn):就為了減少編譯時(shí)「類型擦除」這一步,就提出原生類型規(guī)范,有必要么?
甚至當(dāng)Type Annotations落地后,開(kāi)發(fā)者上線前在進(jìn)行代碼壓縮時(shí),「類型擦除」也會(huì)作為「代碼壓縮」的職責(zé)之一。
從這個(gè)角度看,甚至沒(méi)有減少編譯時(shí)的工作量。
所以提出原生的類型規(guī)范,有必要么?
前端的發(fā)展實(shí)際是一個(gè)「努力去編譯時(shí)流程」的過(guò)程。
比如,編譯時(shí)代碼需要降級(jí),需要polyfill??隨著IE11?停止服務(wù),主流瀏覽器紛紛跟進(jìn)標(biāo)準(zhǔn)落地,降級(jí)與polyfill的需求逐漸變少。
再比如,代碼需要打包?隨著ESM?規(guī)范落地,在當(dāng)前,至少在開(kāi)發(fā)環(huán)境中代碼已經(jīng)不需要打包(使用Vite)。
Type Annotations的出現(xiàn),就是遵循「努力去編譯時(shí)流程」這一趨勢(shì)的產(chǎn)物。
從這個(gè)角度看,還是很有必要的。
參考資料
[1]布達(dá)佩斯2022 JSConf:https://www.youtube.com/watch?v=SdV9Xy0E4CM&list=PL37ZVnwpeshGuMZrOZzEo8QLBjjpbtBGm&index=2。
[2]tc39:https://github.com/tc39。
[3]state of JS:https://stateofjs.com/en-us/。
[4]Github報(bào)告:https://octoverse.github.com/。
[5]grammar-conventions:https://tc39.es/proposal-type-annotations/grammar.html#grammar-conventions。
網(wǎng)頁(yè)題目:原生JS也要支持類型注解啦?
網(wǎng)站鏈接:http://fisionsoft.com.cn/article/dhhidio.html


咨詢
建站咨詢
