譯原文:blog.bitsrc.io/es2020-has-…
做者:Mahdhi Rezvi
譯:圖雀社區javascript
近年來,JavaScript 的發展很是迅速。 尤爲是在2015 年 ES6 發佈以後,狀況變得更好。前端
如今 許多新的特性被提議包括在 ES2020版本中。好消息是這些已經已經敲定。 如今,咱們得到了最終定稿的功能清單,它們將在被批准發佈以後出如今備受期待的 ES2020 中。 其中一些功能使我很是興奮,由於在它們存在以前編寫代碼時遇到將會遇到不少麻煩。 讓咱們看看它們是什麼吧!java
對我我的來講,這是 ES2020最使人興奮的特色之一。 我已經編寫了不少程序,這些程序將會從這個新特性中獲益匪淺。git
可選鏈操做符容許您安全地訪問對象的深嵌套屬性,而沒必要檢查每一個屬性是否存在。 讓咱們看看這個特性對咱們有什麼幫助。正則表達式
const user = {
firstName: "Joseph",
lastName: "Kuruvilla",
age: 38,
address: {
number: "239",
street: "Ludwig Lane",
city: "Chennai",
zip: "600028",
prop1: {
prop2: {
prop3: {
prop4: {
value: "sample",
},
},
},
},
},
};
if (user && user.address) {
console.log(user.address.zip);
//600028
}
if (
user &&
user.address &&
user.address.prop1 &&
user.address.prop1.prop2 &&
user.address.prop1.prop2.prop3 &&
user.address.prop1.prop2.prop3.prop4
) {
console.log(user.address.prop1.prop2.prop3.prop4.value);
//sample
}
//Accessing unexisting property
console.log(user.address.prop102.po);
//Error
複製代碼
正如您在上面看到的,您必須檢查每一個級別中是否存在該屬性,以免出現沒法讀取未定義屬性「 po」的錯誤。 隨着嵌套級別的增長,手動檢查的屬性數量也會增長。 這意味着咱們必須檢查每一個級別,以確保它不會在遇到未定義或空對象時崩潰。瀏覽器
隨着可選鏈式操做符 (Optional Chaining) 的引入,咱們前端的工做變得容易多了。 經過簡單地使用可選鏈式操做符 ?.
咱們能夠訪問深嵌套的對象,而沒必要檢查未定義或空對象。安全
讓咱們看看它是如何運做的。app
const user = {
firstName: "Joseph",
lastName: "Kuruvilla",
age: 38,
address: {
number: "239",
street: "Ludwig Lane",
city: "Chennai",
zip: "600028",
prop1: {
prop2: {
prop3: {
prop4: {
value: "sample",
},
},
},
},
},
};
console.log(user?.address?.zip);
// 600028
console.log(user?.address?.prop1?.prop2?.prop3?.prop4?.value);
// sample
//Accessing unexisting property
console.log(user?.address?.prop102?.po);
//undefined
複製代碼
太神奇了! ES2020 成功地經過引入一個單獨的代碼操做符 ?.
來減小了如此多的代碼行數!ide
這是另外一個令我興奮的功能,當我第一次在 proposal stage, 瞭解到的時候,我由衷的喜歡這個特性,由於我已經歷了編寫單獨的函數來手動檢查這個特性的麻煩。函數
空值合併操做符容許您檢查 nullish
值而不是 falsey
值。 Nullish 值是指 null
或 undefined
的值。 而 falsey 值是諸如空字符串、數字0、 undefined
、 null
、 false
、 NaN
等等的值。 這對你來講可能聽起來沒什麼不一樣,可是在現實中,這意味着不少。
讓咱們看看這是怎麼回事。
我最近作了一個項目,我須要容許黑暗模式(Dark Mode)切換功能。 我必須檢查輸入是 true
仍是 false
。 若是用戶沒有設置任何值,則默認爲 true
。 下面就是我如何在有空值合併操做符以前實現它的:
const darkModePreference1 = true;
const darkModePreference2 = false;
const darkModePreference3 = undefined;
const darkModePreference4 = null;
const getUserDarkModePreference = (darkModePreference) => {
if (darkModePreference || darkModePreference === false) {
return darkModePreference;
}
return true;
};
getUserDarkModePreference(darkModePreference1);
// true
getUserDarkModePreference(darkModePreference2);
// false
getUserDarkModePreference(darkModePreference3);
// true
getUserDarkModePreference(darkModePreference4);
// true
複製代碼
在有空值合併操做符以後,您所要作的就是使用 ??
操做符。不須要 if
語句:
const darkModePreference1 = true;
const darkModePreference2 = false;
const darkModePreference3 = undefined;
const darkModePreference4 = null;
const getUserDarkModePreference = (darkModePreference) => {
return darkModePreference ?? true;
};
getUserDarkModePreference(darkModePreference1);
// true
getUserDarkModePreference(darkModePreference2);
// false
getUserDarkModePreference(darkModePreference3);
// true
getUserDarkModePreference(darkModePreference4);
// true
複製代碼
這裏基本上發生的狀況是,若是變量 darkModePreference 包含一個 nullish
值,那麼將值 true 賦給它。 簡單,簡短,易於理解。
這個特性將幫助您的應用程序更加高效的執行, 動態 import 容許您將 JS 文件做爲原生應用用程序中的模塊動態導入。 在 ES2020以前,不論是否使用模塊,都應該導入模塊。
例如,假設咱們須要添加一個功能來下載 pdf 格式的文件。
讓咱們看看如何在 動態 import 以前和以後實現這一點。
實際上,不會全部的頁面訪問者使用下載 pdf 的選項。 可是,不管咱們的訪客是否使用它,它仍然須要被導入。 這意味着這個 pdf 模塊也能夠在頁面加載期間被下載。
import { exportAsPdf } from "./export-as-pdf.js";
const exportPdfButton = document.querySelector(".exportPdfBtn");
exportPdfButton.addEventListener("click", exportAsPdf);
複製代碼
這種開銷能夠經過使用延遲加載模塊(lazy loaded modules)來減小。 能夠經過稱爲代碼分割 (code-splitting)的方法來實現,這在 Webpack 或其餘模塊打包工具已經可使用了。 可是對於 ES2020,咱們能夠直接使用它了,而不須要模塊打包工具,如 Webpack。
const exportPdfButton = document.querySelector('.exportPdfBtn');
exportPdfButton.addEventListener('click', () => {
import('./export-as-pdf.js')
.then(module => {
module.exportAsPdf()
})
.catch(err => {
// handle the error if the module fails to load
})
})
複製代碼
正如您在上面的代碼中看到的,如今只有在須要模塊時才延遲加載模塊。 從而減小開銷和頁面加載時間。
若是你有一個場景,在全部 Promise 都完成以後必須執行一個任務,那麼你可能使用 Promise.all()
方法。 可是這個方法有一個缺點。 當你的任何一個 Promise 被 Rejected 時,Promise 方法就會拋出一個錯誤。 這意味着您的代碼不會等到全部的 Promise 都完成。
這可能不是你想要的。 若是你想要這樣的東西: 「我不在意他們的結果。 只需所有運行」 ,那麼你可使用新的 Promise.allSettled()
方法。 這種方法只有在你的全部 Promise 都 settled
ーー 要麼 Resolved
,要麼 Rejected
ーー 時纔會 Resolved
。
const PromiseArray = [
Promise.resolve(100),
Promise.reject(null),
Promise.resolve("Data release"),
Promise.reject(new Error("Something went wrong")),
];
Promise.all(PromiseArray)
.then((data) =>
console.log("all resolved! here are the resolve values:", data)
)
.catch((err) => console.log("got rejected! reason:", err));
//got rejected! reason: null
複製代碼
如上所述,當其中一個 Promise 被 rejected
時, Promise 就會拋出錯誤。
const PromiseArray = [
Promise.resolve(100),
Promise.reject(null),
Promise.resolve("Data release"),
Promise.reject(new Error("Something went wrong")),
];
Promise.allSettled(PromiseArray)
.then((res) => {
console.log(res);
})
.catch((err) => console.log(err));
//[
// {status: "fulfilled", value: 100},
// {status: "rejected", reason: null},
// {status: "fulfilled", value: "Data release"},
// {status: "rejected", reason: Error: Something went wrong ...}
//]
複製代碼
儘管有些 Promise 被 rejected
了,Promise.allSettled 返回了全部的 Promise 的結果。
globalThis
包含對全局對象的引用,與環境無關。 在瀏覽器中,全局對象是 window
對象。 在 Node 環境中,全局對象是 global
或者 Web workers 中的 self
。
咱們在工做中會有須要編寫一份同時運行在 Node 和瀏覽器中的通用代碼,當咱們要取得全局對象時,一般須要作不少工做和邏輯判斷:
beforeGlobalThis = (typeof window !== "undefined"
? window
: (typeof process === 'object' &&
typeof require === 'function' &&
typeof global === 'object')
? global
: this);
beforeGlobalThis.tuture = '小若燕雀,亦可一展宏圖';
複製代碼
咱們能夠直接使用 globalThis
去引用全局對象,而不用去擔憂環境的問題:
globalThis.tuture = '小若燕雀,亦可一展宏圖';
複製代碼
上面的代碼在瀏覽器或者 Node 環境中都是通用的,你能夠放心使用!
容許您使用大於 Javascript 中容許的最大值的數字。 這個數字是 pow(2,53)-1
。 儘管這不能向後兼容,由於傳統的數字系統(IEEE 754)不能支持這種大小的數字。
matchAll()
是一個與正則表達式相關的方法。 此方法返回與正則表達式匹配的字符串的全部結果的迭代器,包括捕獲組。 這個方法已經被添加到 String 原型中。
ES2020 中那個特性最讓你興奮?歡迎在評論中發表你的見解!✌️
Happy Coding!
想要學習更多精彩的實戰技術教程?來圖雀社區逛逛吧。