摘要:舉例來說即便某個失敗了,也不會導致的發生,這樣在不在乎是否有項目失敗,只要拿到都結束的信號的場景很有用。對于則稍有不同只要有子項,就會完成,哪怕第一個了,而第二個了,也會,而對于,這種場景會直接。
1. 引言
本周精讀的內容是:Google I/O 19。
2019 年 Google I/O 介紹了一些激動人心的 JS 新特性,這些特性有些已經被主流瀏覽器實現,并支持 polyfill,有些還在草案階段。
我們可以看到 JS 語言正變得越來越嚴謹,不同規范間也逐漸完成了閉環,而且在不斷吸納其他語言的優秀特性,比如 WeakRef,讓 JS 在成為使用范圍最廣編程語言的同時,也越成為編程語言的集大成者,讓我們有信心繼續跟隨 JS 生態,不用被新生的小語種分散精力。
2. 精讀本視頻共介紹了 16 個新特性。
private class fields私有成員修飾符,用于 Class:
class IncreasingCounter { #count = 0; get value() { return this.#count; } increment() { this.#count++; } }
通過 # 修飾的成員變量或成員函數就成為了私有變量,如果試圖在 Class 外部訪問,則會拋出異常:
const counter = new IncreasingCounter() counter.#count // -> SyntaxError counter.#count = 42 // -> SyntaxError
雖然 # 這個關鍵字被吐槽了很多次,但結論已經塵埃落定了,只是個語法形式而已,不用太糾結。
目前僅 Chrome、Nodejs 支持。
Regex matchAll正則匹配支持了 matchAll API,可以更方便進行正則遞歸了:
const string = "Magic hex number: DEADBEEF CAFE" const regex = /p{ASCII_Hex_Digit}+/gu/ for (const match of string.matchAll(regex)) { console.log(match) } // Output: // ["DEADBEEF", index: 19, input: "Magic hex number: DEADBEEF CAFE"] // ["CAFE", index: 28, input: "Magic hex number: DEADBEEF CAFE"]
相比以前在 while 語句里循環正則匹配,這個 API 真的是相當的便利。And more,還順帶提到了 Named Capture Groups,這個在之前的 精讀《正則 ES2018》 中也有提到,具體可以點過去閱讀,也可以配合 matchAll 一起使用。
Numeric literals大數字面量的支持,比如:
1234567890123456789 * 123; // -> 151851850485185200000
這樣計算結果是丟失精度的,但只要在數字末尾加上 n,就可以正確計算大數了:
1234567890123456789n * 123n; // -> 151851850485185185047n
目前 BigInt 已經被 Chrome、Firefox、Nodejs 支持。
BigInt formatting為了方便閱讀,大數還支持了國際化,可以適配成不同國家的語言表達形式:
const nf = new Intl.NumberFormat("fr"); nf.format(12345678901234567890n); // -> "12 345 678 901 234 567 890"
記住 Intl 這個內置變量,后面還有不少國際化用途。
同時,為了方便程序員閱讀代碼,大數還支持帶下劃線的書寫方式:
const nf = new Intl.NumberFormat("fr"); nf.format(12345678901234567890n); // -> "12 345 678 901 234 567 890"
目前已經被 Chrome、Firefox、Nodejs 支持。
flat & flatmap等價于 lodash flatten 功能:
const array = [1, [2, [3]]]; array.flat(); // -> [1, 2, [3]]
還支持自定義深度,如果支持 Infinity 無限層級:
const array = [1, [2, [3]]]; array.flat(Infinity); // -> [1, 2, 3]
這樣我們就可以配合 .map 使用:
[2, 3, 4].map(duplicate).flat();
因為這個用法太常見,js 內置了 flatMap 函數代替 map,與上面的效果是等價的:
[2, 3, 4].flatMap(duplicate);
目前已經被 Chrome、Firefox、Safari、Nodejs 支持。
fromEntriesfromEntries 是 Object.fromEntries 的語法,用來將對象轉化為數組的描述:
const object = { x: 42, y: 50, abc: 9001 }; const entries = Object.entries(object); // -> [["x", 42], ["y", 50]]
這樣就可以對對象的 key 與 value 進行加工處理,并通過 fromEntries API 重新轉回對象:
const object = { x: 42, y: 50, abc: 9001 } const result Object.fromEntries( Object.entries(object) .filter(([ key, value]) => key.length === 1) .map(([ key, value ]) => [ key, value * 2]) ) // -> { x: 84, y: 100 }
不僅如此,還可以將 object 快速轉化為 Map:
const map = new Map(Object.entries(object));
目前已經被 Chrome、Firefox、Safari、Nodejs 支持。
Map to Object conversionfromEntries 建立了 object 與 map 之間的橋梁,我們還可以將 Map 快速轉化為 object:
const objectCopy = Object.fromEntries(map);
目前已經被 Chrome、Firefox、Safari、Nodejs 支持。
globalThis業務代碼一般不需要訪問全局的 window 變量,但是框架與庫一般需要,比如 polyfill。
訪問全局的 this 一般會做四個兼容,因為 js 在不同運行環境下,全局 this 的變量名都不一樣:
const getGlobalThis = () => { if (typeof self !== "undefined") return self; // web worker 環境 if (typeof window !== "undefined") return window; // web 環境 if (typeof global !== "undefined") return global; // node 環境 if (typeof this !== "undefined") return this; // 獨立 js shells 腳本環境 throw new Error("Unable to locate global object"); };
因此整治一下規范也合情合理:
globalThis; // 在任何環境,它就是全局的 this
目前已經被 Chrome、Firefox、Safari、Nodejs 支持。
Stable sort就是穩定排序結果的功能,比如下面的數組:
const doggos = [ { name: "Abby", rating: 12 }, { name: "Bandit", rating: 13 }, { name: "Choco", rating: 14 }, { name: "Daisy", rating: 12 }, { name: "Elmo", rating: 12 }, { name: "Falco", rating: 13 }, { name: "Ghost", rating: 14 } ]; doggos.sort((a, b) => b.rating - a.rating);
最終排序結果可能如下:
[ { name: "Choco", rating: 14 }, { name: "Ghost", rating: 14 }, { name: "Bandit", rating: 13 }, { name: "Falco", rating: 13 }, { name: "Abby", rating: 12 }, { name: "Daisy", rating: 12 }, { name: "Elmo", rating: 12 } ];
也可能如下:
[ { name: "Ghost", rating: 14 }, { name: "Choco", rating: 14 }, { name: "Bandit", rating: 13 }, { name: "Falco", rating: 13 }, { name: "Abby", rating: 12 }, { name: "Daisy", rating: 12 }, { name: "Elmo", rating: 12 } ];
注意 choco 與 Ghost 的位置可能會顛倒,這是因為 JS 引擎可能只關注 sort 函數的排序,而在順序相同時,不會保持原有的排序規則。現在通過 Stable sort 規范,可以確保這個排序結果是穩定的。
目前已經被 Chrome、Firefox、Safari、Nodejs 支持。
Intl.RelativeTimeFormatIntl.RelativeTimeFormat 可以對時間進行語義化翻譯:
const rtf = new Intl.RelativeTimeFormat("en", { numeric: "auto" }); rtf.format(-1, "day"); // -> "yesterday" rtf.format(0, "day"); // -> "today" rtf.format(1, "day"); // -> "tomorrow" rtf.format(-1, "week"); // -> "last week" rtf.format(0, "week"); // -> "this week" rtf.format(1, "week"); // -> "next week"
不同語言體系下,format 會返回不同的結果,通過控制 RelativeTimeFormat 的第一個參數 en 決定,比如可以切換為 ta-in。
Intl.ListFormatListFormat 以列表的形式格式化數組:
const lfEnglish = new Intl.ListFormat("en"); lfEnglish.format(["Ada", "Grace"]); // -> "Ada and Grace"
可以通過第二個參數指定連接類型:
const lfEnglish = new Intl.ListFormat("en", { type: "disjunction" }); lfEnglish.format(["Ada", "Grace"]); // -> "Ada or Grace"
目前已經被 Chrome、Nodejs 支持。
Intl.DateTimeFormat -> formatRangeDateTimeFormat 可以定制日期格式化輸出:
const start = new Date(startTimestamp); // -> "May 7, 2019" const end = new Date(endTimestamp); // -> "May 9, 2019" const fmt = new Intl.DateTimeFormat("en", { year: "numeric", month: "long", day: "numeric" }); const output = `${fmt.format(start)} - ${fmt.format(end)}`; // -> "May 7, 2019 - May 9, 2019"
最后一句,也可以通過 formatRange 函數代替:
const output = fmt.formatRange(start, end); // -> "May 7 - 9, 2019"
目前已經被 Chrome 支持。
Intl.Locale定義國際化本地化的相關信息:
const locale = new Intl.Locale("es-419-u-hc-h12", { calendar: "gregory" }); locale.language; // -> "es" locale.calendar; // -> "gregory" locale.hourCycle; // -> "h12" locale.region; // -> "419" locale.toString(); // -> "es-419-u-ca-gregory-hc-h12"
目前已經被 Chrome、Nodejs 支持。
Top-Level await支持在根節點生效 await,比如:
const result = await doSomethingAsync(); doSomethingElse();
目前還沒有支持。
Promise.allSettled/Promise.anyPromise.allSettled 類似 Promise.all、Promise.any 類似 Promise.race,區別是,在 Promise reject 時,allSettled 不會 reject,而是也當作 fulfilled 的信號。
舉例來說:
const promises = [ fetch("/api-call-1"), fetch("/api-call-2"), fetch("/api-call-3") ]; await Promise.allSettled(promises);
即便某個 fetch 失敗了,也不會導致 reject 的發生,這樣在不在乎是否有項目失敗,只要拿到都結束的信號的場景很有用。
對于 Promise.any 則稍有不同:
const promises = [ fetch("/api-call-1"), fetch("/api-call-2"), fetch("/api-call-3") ]; try { const first = await Promise.any(promises); // Any of ths promises was fulfilled. console.log(first); } catch (error) { // All of the promises were rejected. }
只要有子項 fulfilled,就會完成 Promise.any,哪怕第一個 Promise reject 了,而第二個 Promise fulfilled 了,Promise.any 也會 fulfilled,而對于 Promise.race,這種場景會直接 rejected。
如果所有子項都 rejected,那 Promise.any 也只好 rejected 啦。
目前已經被 Chrome、Firefox 支持。
WeakRefWeakRef 是從 OC 抄過來的弱引用概念。
為了解決這個問題:當對象被引用后,由于引用的存在,導致對象無法被 GC。
所以如果建立了弱引用,那么對象就不會因為存在的這段引用關系而影響 GC 了!
具體用法是:
const obj = {}; const weakObj = new WeakRef(obj);
使用 weakObj 與 obj 沒有任何區別,唯一不同時,obj 可能隨時被 GC,而一旦被 GC,弱引用拿到的對象可能就變成 undefined,所以要做好錯誤保護。
3. 總結JS 這幾個特性提升了 JS 語言的成熟性、完整性,而且看到其訪問控制能力、規范性、國際化等能力有著重加強,解決的都是 JS 最普遍遇到的痛點問題。
那么,這些 JS 特性中,你最喜歡哪一條呢?想吐槽哪一條呢?歡迎留言。
討論地址是:精讀《What"s new in javascript》 · Issue #159 · dt-fe/weekly
如果你想參與討論,請 點擊這里,每周都有新的主題,周末或周一發布。前端精讀 - 幫你篩選靠譜的內容。
關注 前端精讀微信公眾號
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/104346.html
摘要:一般會每隔周發布一次主版本。于是我就制作了中文字幕并將視頻發到了。站地址中文字幕在開發者博客上,文章也已經在月份發布了,文中提到視頻會在年月底發布,到時候我會繼續制作中文字幕。 大家好,這是代碼之聲(codefm)第一期,今天給大家帶來的是 Whats New In DevTools (Chrome 63)。 Chrome 一般會每隔 6 周發布一次主版本。?目前 Chrome 的最新...
摘要:一般會每隔周發布一次主版本。于是我就制作了中文字幕并將視頻發到了。站地址中文字幕在開發者博客上,文章也已經在月份發布了,文中提到視頻會在年月底發布,到時候我會繼續制作中文字幕。 大家好,這是代碼之聲(codefm)第一期,今天給大家帶來的是 Whats New In DevTools (Chrome 63)。 Chrome 一般會每隔 6 周發布一次主版本。?目前 Chrome 的最新...
摘要:在和中都保留了數組的強引用,所以在中簡單的清除變量內存并沒有得到釋放,因為還存在引用計數。而在中,它的鍵是弱引用,不計入引用計數中,所以當被清除之后,數組會因為引用計數為而被回收掉。其實我們主要注意的引用是不計引用計數的,就好理解了。 showImg(https://segmentfault.com/img/remote/1460000019147368?w=900&h=383); 前...
摘要:一個表示編譯器檢測到一個無效的引用值。在實際情況中,往往是在獲取一個未被賦值的引用時被拋出。任何一個函數上下文都有一個被稱為活動對象的變量對象。沒有找到的話,就會認為引用名沒有基礎值并拋出的錯誤。下沒有下的屬性僅存在于被啟動的情況下。 和其他語言相比,javascript中的對于undefined的理解還是有點讓人困惑的。特別是試著理解ReferenceErrors錯誤(x is no...
摘要:彈出的就是,歲。值得注意的是,和都是改變上下文中的并立即執行這個函數,方法改變了指向之后會返回一個函數,可以隨時調用。和作用完全一樣,只是傳參的方式不一樣。以上,有錯希望各位大神斧正。 apply bind call這三個方法,作用都是改變當前使用該方法的對象的this指向。但三個方法還是有一些區別,先說說共同點。 window.person = { name: mice...
閱讀 3448·2021-10-14 09:42
閱讀 2738·2021-09-08 10:44
閱讀 1313·2021-09-02 10:18
閱讀 3628·2021-08-30 09:43
閱讀 2808·2021-07-29 13:49
閱讀 3730·2019-08-29 17:02
閱讀 1589·2019-08-29 15:09
閱讀 1042·2019-08-29 11:01