摘要:本文主要介紹幾個已經進入stage4的提案,這幾個提案有望在2022年逐步納入標準。
本文分享自華爲雲社區《2022 年你應該嘗試的 8個 JavaScript 新功能》,作者:前端picker。
1995年12月4日,Netscape 公司與 Sun 公司聯合發佈JavaScript 以來,JavaScript從推出就開始了飛速的發展,2015年6,ES6正式發佈,此後JavaScript正式進入新階段,成爲企業級大規模開發語言,並仍以高速度不斷髮展。
下面的表格對應這版本變化:
本文主要介紹幾個已經進入stage4的提案,這幾個提案有望在2022年逐步納入標準。(請注意:納入標準並不等同於瀏覽器支持)
PS:科普-Javascript的新語法,從提出到納入標準一共經歷下面幾個stage
stage-0:新語法還是一個設想,(只能由TC39成員或TC39貢獻者提出)
stage-1::提案階段,比較正式的提議,只能由TC39成員發起,這個提案要解決的問題必須有正式的書面描述。
stage-2:草案,有了初始規範,必須對功能語法和語義進行正式描述,包括一些實驗性的實現。
stage-3:候選,該提議基本已經實現,需要等待實驗驗證,用戶反饋及驗收測試通過。
stage-4:已完成,必須通過 Test262 驗收測試,下一步就納入ECMA標準。
.at()
TC39建議在所有基本可索引類,例如:數組、字符串、類數組(arguments)中添加.at()方法。
例如
lat arr=[1,2,3,4,5]
之前我們想獲取數組中的第二位
arr[1] //2
最後一位的話,可能就是
arr[4] // 5
但是如果arr長度是動態的呢?我們要如何讓取出最後一位? 通常的寫法是:
arr[arr.length-1]
但是有了.at()方法就很簡單了,.at()支持正索引和負索引。
例如
arr.at(-1) //5 arr.at(-2) //4
具體提案:https://github.com/tc39/proposal-relative-indexing-method
Object.hasOwn(object, property)
Object.hasOwn(object, property)主要是用來替代Object.prototype.hasOwnProperty()。
目前我們想要判斷對象是否具有指定的對象,主要寫法如下:
if (Object.prototype.hasOwnProperty.call(object, "fn")) { console.log('有') }
而Object.hasOwn的寫法:
if (Object.hasOwn(object, "fn")) { console.log("有") }
具體提案:https://github.com/tc39/proposal-accessible-object-hasownproperty
目前來看,V8引擎的9.3版本已經開始支持,所以說chrome應該會很快支持。
類的私有方法和getter/setter
類是所有支持面嚮對象語言的基本,而Javascript雖然支持使用class定義類,但是並沒有提供 定義私有屬性/方法的的 方案。本提案提出使用**#**來定義私有屬性/方法
class Person{ name = '小芳'; #age = 16; consoleAge(){ console.log(this.#age) } } const person = new Person(); console.log(person.name); //小芳 console.log(button.#value); //報錯 button.#value = false;//報錯
具體提案:https://github.com/tc39/proposal-private-methods
檢查私有屬性和方法
因爲新的標準會支持私有屬性和方法,當我們訪問不存在的私有屬性/方法會報錯,而在新標準中也考慮了這個情況,提供了in來檢查私有屬性和方法是否存在
class C { #brand; #method() {} get #getter() {} static isC(obj) { return #brand in obj && #method in obj && #getter in obj; } }
具體提案:https://github.com/tc39/proposal-private-fields-in-in
Top-level await(頂層await)
目前,我們使用await必須是在申明async的函數中,本提案,主要是支持在沒有async的情況下使用await
例如下面幾種使用場景:
動態引入依賴
const strings = await import(`/i18n/${navigator.language}`);
這允許模塊使用運行時值來確定依賴關係。這對於開發/生產拆分、國際化、環境拆分等非常有用。
資源初始化
const connection = await dbConnector();
這允許模塊表示資源,並在模塊永遠無法使用的情況下產生錯誤。
加載依賴
let jQuery; try { jQuery = await import('https://cdn-a.com/jQuery'); } catch { jQuery = await import('https://cdn-b.com/jQuery'); }
具體提案:https://github.com/tc39/proposal-top-level-await
正則匹配索引
該提案提供了一個新的/d,用來獲取每個匹配的開始位置和結束位置信息。
const str = 'The question is TO BE, or not to be, that is to be.'; const regex = /to be/gd; const matches = [...str.matchAll(regex)]; matches[0];
具體提案:https://github.com/tc39/proposal-regexp-match-indices
new Error()拋出異常的具體原因
new Error(),可能大家第一反應是,這不是已經存在的語法嘛,是的,沒錯!只是新的提案:將錯誤與原因相關聯,,向具有屬性的Error() 構造函數添加一個附加選項參數cause,其值將作爲屬性分配給錯誤實例。
async function doJob() { const rawResource = await fetch('//domain/resource-a') .catch(err => { throw new Error('Download raw resource failed', { cause: err }); }); const jobResult = doComputationalHeavyJob(rawResource); await fetch('//domain/upload', { method: 'POST', body: jobResult }) .catch(err => { throw new Error('Upload job result failed', { cause: err }); }); } try { await doJob(); } catch (e) { console.log(e); console.log('Caused by', e.cause); } // Error: Upload job result failed // Caused by TypeError: Failed to fetch
具體提案:https://github.com/tc39/proposal-error-cause
類static初始化塊
本田針對靜態字段和靜態私有字段的提供了一種在 ClassDefinitionEvaluation 期間執行類靜態端的每個字段初始化的機制-static blocks.例如官方提供的例子:
在沒有static blocks之前,我們想給靜態變量初始化(非直接賦值,可能是表達式賦值)的話,可能是放在外部實現:
// without static blocks: class C { static x = ...; static y; static z; } try { const obj = doSomethingWith(C.x); C.y = obj.y C.z = obj.z; } catch { C.y = ...; C.z = ...; }
有了static block的情況下:我們可以直接在static blocks中初始化變量:
class C { static x = ...; static y; static z; static { try { const obj = doSomethingWith(this.x); this.y = obj.y; this.z = obj.z; } catch { this.y = ...; this.z = ...; } } }