ES2020 新特性(種草)

 更新時間:2020-01-12 19:00:26   作者:佚名   我要評論(0)

這幾年,Ecma TC39一年一次更新 ecmascript 規范標準,截止目前,以下特性已進入 finished 狀態,F在帶大家體驗種草 ES2020 新特性。


一:Promise.allSettled

這幾年,Ecma TC39一年一次更新 ecmascript 規范標準,截止目前,以下特性已進入 finished 狀態,F在帶大家體驗種草 ES2020 新特性。

一:Promise.allSettled

Promise.all 缺陷

都知道 Promise.all 具有并發執行異步任務的能力。但它的最大問題就是如果其中某個任務出現異常(reject),所有任務都會掛掉,Promise直接進入 reject  狀態。

想象這個場景:你的頁面有三個區域,分別對應三個獨立的接口數據,使用 Promise.all 來并發三個接口,如果其中任意一個接口服務異常,狀態是reject,這會導致頁面中該三個區域數據全都無法渲染出來,因為任何 reject 都會進入catch回調, 很明顯,這是無法接受的,如下:

Promise.all([
  Promise.reject({code: 500, msg: '服務異常'}),
  Promise.resolve({ code: 200, list: []}),
  Promise.resolve({code: 200, list: []})
])
.then((ret) => {
  // 如果其中一個任務是 reject,則不會執行到這個回調。
  RenderContent(ret);
})
.catch((error) => {
  // 本例中會執行到這個回調
  // error: {code: 500, msg: "服務異常"}
})

我們需要一種機制,如果并發任務中,無論一個任務正;蛘弋惓,都會返回對應的的狀態(fulfilled 或者 rejected)與結果(業務value 或者 拒因 reason),在 then 里面通過 filter 來過濾出想要的業務邏輯結果,這就能最大限度的保障業務當前狀態的可訪問性,而 Promise.allSettled 就是解決這問題的。

Promise.allSettled([
  Promise.reject({code: 500, msg: '服務異常'}),
  Promise.resolve({ code: 200, list: []}),
  Promise.resolve({code: 200, list: []})
])
.then((ret) => {
  /*
    0: {status: "rejected", reason: {…}}
    1: {status: "fulfilled", value: {…}}
    2: {status: "fulfilled", value: {…}}
  */
  // 過濾掉 rejected 狀態,盡可能多的保證頁面區域數據渲染
  RenderContent(ret.filter((el) => {
    return el.status !== 'rejected';
  }));
});

二:可選鏈(Optional chaining)

可選鏈 可讓我們在查詢具有多層級的對象時,不再需要進行冗余的各種前置校驗。

日常開發中,我們經常會遇到這種查詢

var name = user && user.info && user.info.name;

又或是這種

var age = user && user.info && user.info.getAge && user.info.getAge();

這是一種丑陋但又不得不做的前置校驗,否則很容易命中 Uncaught TypeError: Cannot read property... 這種錯誤,這極有可能讓你整個應用掛掉。

用了 Optional Chaining ,上面代碼會變成

var name = user?.info?.name;
var age = user?.info?.getAge?.();

可選鏈中的 ? 表示如果問號左邊表達式有值, 就會繼續查詢問號后面的字段。根據上面可以看出,用可選鏈可以大量簡化類似繁瑣的前置校驗操作,而且更安全。

三:空值合并運算符(Nullish coalescing Operator)

當我們查詢某個屬性時,經常會遇到,如果沒有該屬性就會設置一個默認的值。比如下面代碼中查詢玩家等級。

var level = (user.data && user.data.level) || '暫無等級';

在JS中,空字符串、0 等,當進行邏輯操作符判時,會自動轉化為 false。在上面的代碼里,如果玩家等級本身就是 0 級, 變量 level 就會被賦值 暫無等級 字符串,這是邏輯錯誤。

var level;
if (typeof user.level === 'number') {
  level = user.level;
} else if (!user.level) {
  level = '暫無等級';
} else {
  level = user.level;
}

來看看用空值合并運算符如何處理

// {
//  "level": 0  
// }
var level = `${user.level}級` ?? '暫無等級';
// level -> '0級'

用空值合并運算在邏輯正確的前提下,代碼更加簡潔。

空值合并運算符 與 可選鏈 相結合,可以很輕松處理多級查詢并賦予默認值問題。

var level = user.data?.level ?? '暫無等級';

四:dynamic-import

按需 import 提案幾年前就已提出,如今終于能進入ES正式規范。這里個人理解成“按需”更為貼切,F代前端打包資源越來越大,打包成幾M的JS資源已成常態,而往往前端應用初始化時根本不需要全量加載邏輯資源,為了首屏渲染速度更快,很多時候都是按需加載,比如懶加載圖片等。而這些按需執行邏輯資源都體現在某一個事件回調中去加載。

el.onclick = () => {
  import(`/path/current-logic.js`)
  .then((module) => {
    module.doSomthing();
  })
  .catch((err) => {
    // load error;
  })
}

當然,webpack目前已很好的支持了該特性。

五:globalThis

Javascript 在不同的環境獲取全局對象有不通的方式,node 中通過 global, web中通過 window, self 等,有些甚至通過 this 獲取,但通過 this 是及其危險的,this 在 js 中異常復雜,它嚴重依賴當前的執行上下文,這些無疑增加了獲取全局對象的復雜性。

過去獲取全局對象,可通過一個全局函數

var getGlobal = function () { 
 if (typeof self !== 'undefined') { return self; } 
 if (typeof window !== 'undefined') { return window; } 
 if (typeof global !== 'undefined') { return global; } 
 throw new Error('unable to locate global object'); 
}; 

var globals = getGlobal(); 

// https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/globalThis

而 globalThis 目的就是提供一種標準化方式訪問全局對象,有了 globalThis 后,你可以在任意上下文,任意時刻都能獲取到全局對象。

六:BigInt

Js 中 Number類型只能安全的表示-(2^53-1)至 2^53-1 范的值,即Number.MIN_SAFE_INTEGER 至Number.MAX_SAFE_INTEGER,超出這個范圍的整數計算或者表示會丟失精度。

var num = Number.MAX_SAFE_INTEGER; // -> 9007199254740991

num = num + 1; // -> 9007199254740992

// 再次加 +1 后無法正常運算
num = num + 1; // -> 9007199254740992

// 兩個不同的值,卻返回了true
9007199254740992 === 9007199254740993 // -> true

為解決此問題,ES2020提供一種新的數據類型:BigInt。

使用 BigInt 有兩種方式:

在整數字面量后面加n。

var bigIntNum = 9007199254740993n;

使用 BigInt 函數。

var bigIntNum = BigInt(9007199254740);
var anOtherBigIntNum = BigInt('9007199254740993');

通過 BigInt, 我們可以安全的進行大數整型計算。

var bigNumRet = 9007199254740993n + 9007199254740993n; // -> -> 18014398509481986n

bigNumRet.toString(); // -> '18014398509481986'

注意:

BigInt 是一種新的數據原始(primitive)類型。

typeof 9007199254740993n; // -> 'bigint'

盡可能避免通過調用函數 BigInt 方式來實例化超大整型。因為參數的字面量實際也是 Number 類型的一次實例化,超出安全范圍的數字,可能會引起精度丟失。

七:String.prototype.matchAll

思考下面代碼

var str = '<text>JS</text><text>正則</text>';
var reg = /<\w+>(.*?)<\/\w+>/g;

console.log(str.match(reg));
// -> ["<text>JS</text>", "<text>正則</text>"]

可以看出返回的數組里包含了父匹配項,但未匹配到子項(group)。移除全局搜索符“g”試試。

var str = '<text>JS</text><text>正則</text>';
// 注意這里沒有全局搜素標示符“g”
var reg = /<\w+>(.*?)<\/\w+>/;
console.log(str.match(reg));

// 上面會打印出
/*
[
  "<text>JS</text>", 
  "JS", 
  index: 0, 
  input: 
  "<text>JS</text><text>正則</text>", 
  groups: undefined
]
*/

這樣可以獲取到匹配的父項,包括子項(group),但只能獲取到第一個滿足的匹配字符。能看出上面無法匹配到<text>正則</text>。

如果獲取到全局所有匹配項,包括子項呢?

ES2020提供了一種簡易的方式:String.prototype.matchAll, 該方法會返回一個迭代器。

var str = '<text>JS</text><text>正則</text>';
var allMatchs = str.matchAll(/<\w+>(.*?)<\/\w+>/g);

for (const match of allMatchs) {
 console.log(match);
}



/*
第一次迭代返回:
[
  "<text>JS</text>", 
  "JS", 
  index: 0, 
  input: "<text>JS</text><text>正則</text>", 
  groups: undefined
]

第二次迭代返回:
[
  "<text>正則</text>", 
  "正則", 
  index: 15, 
  input: "<text>JS</text><text>正則</text>", 
  groups: undefined
]
*/

能看出每次迭代中可獲取所有的匹配,以及本次匹配的成功的一些其他元信息。

參考資料

github.com/tc39/proposals/blob/master/finished-proposals.md
prop-tc39.now.sh/

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。

您可能感興趣的文章:

  • ES6新特性之模塊Module用法詳解
  • ES6新特性之類(Class)和繼承(Extends)相關概念與用法分析
  • JavaScript ES6的新特性使用新方法定義Class
  • JavaScript中的Reflect對象詳解(ES6新特性)
  • ES6中非常實用的新特性介紹
  • ES6新特性之變量和字符串用法示例
  • ES6新特性七:數組的擴充詳解
  • ES6新特性八:async函數用法實例詳解
  • ES6新特性之字符串的擴展實例分析
  • ES6的新特性概覽

相關文章

  • ES2020 新特性(種草)

    ES2020 新特性(種草)

    這幾年,Ecma TC39一年一次更新 ecmascript 規范標準,截止目前,以下特性已進入 finished 狀態,F在帶大家體驗種草 ES2020 新特性。 一:Promise.allSettled
    2020-01-12
  • Python 實現遞歸法解決迷宮問題的示例代碼

    Python 實現遞歸法解決迷宮問題的示例代碼

    迷宮問題 問題描述: 迷宮可用方陣 [m, n] 表示,0 表示可通過,1 表示不能通過。若要求左上角 (0, 0) 進入,設計算法尋求一條能從右下角 (m-1, n-1) 出去的路徑。
    2020-01-12
  • html2canvas屬性和使用方法以及如何使用html2canvas將HTML內容寫入Canvas生成圖片

    html2canvas屬性和使用方法以及如何使用html2canvas將HTML內容寫入Canvas生成圖片

    如何使用JS截取HTML頁面為圖片呢,下面為大家介紹一款JS截圖插件html2canvas.js html2canvas.js 能夠實現在用戶瀏覽器端直接對整個或部分頁面進行截屏。 html2can
    2020-01-12
  • golang并發編程的實現

    golang并發編程的實現

    go main函數的執行本身就是一個協程,當使用go關鍵字的時候,就會創建一個新的協程 channel channel 管道,用于在多個協程之間傳遞信號 無緩存管道 當對無
    2020-01-12
  • python opencv實現信用卡的數字識別

    python opencv實現信用卡的數字識別

    本項目利用python以及opencv實現信用卡的數字識別 前期準備 導入工具包 定義功能函數 模板圖像處理 讀取模板圖像 cv2.imread(img) 灰度化處理 cv2
    2020-01-12
  • 2019年度web前端面試題總結(主要為Vue面試題)

    2019年度web前端面試題總結(主要為Vue面試題)

    畢業之后就在一直合肥小公司工作,沒有老司機、沒有技術氛圍,在技術的道路上我只能獨自摸索。老板也只會畫餅充饑,前途一片迷?床坏饺魏蜗M。于是乎,我果斷辭
    2020-01-12
  • 深入理解redux之compose的具體應用

    深入理解redux之compose的具體應用

    應用 最近給自己的react項目添加redux的時候,用到了redux中的compose函數,使用compose來增強store,下面是我在項目中的一個應用: import {createStore,apply
    2020-01-12
  • Java使用DateTimeFormatter實現格式化時間

    Java使用DateTimeFormatter實現格式化時間

    用掃描器獲取輸入的時間(年月日時分),這個時間的格式是常用的格式,然后格式化這個時間,把格式化的時間輸出到控制臺,可以在控制臺重復輸入時間.格式化的時間參考企業
    2020-01-12
  • Ranorex通過Python將報告發送到郵箱的方法

    Ranorex通過Python將報告發送到郵箱的方法

    Ranorex測試報告如何發送到郵箱在網上看了下,其實可以通過在Ranorex上或者VS調用編寫發送郵箱代碼就可以執行發送了,RX主要涉及到的開發語言是C++或者.NET。但是我
    2020-01-12
  • 通過實例解析JMM和Volatile底層原理

    通過實例解析JMM和Volatile底層原理

    這篇文章主要介紹了通過實例解析JMM和Volatile底層原理,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下 JMM和
    2020-01-11

最新評論

双色球基本走势图200