欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

ES2020 新特性(種草)

 更新時(shí)間:2020年01月12日 15:30:29   作者:blue_yang  
這篇文章主要介紹了ES2020 新特性(種草),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧

這幾年,Ecma TC39一年一次更新 ecmascript 規(guī)范標(biāo)準(zhǔn),截止目前,以下特性已進(jìn)入 finished 狀態(tài)?,F(xiàn)在帶大家體驗(yàn)種草 ES2020 新特性。

一:Promise.allSettled

Promise.all 缺陷

都知道 Promise.all 具有并發(fā)執(zhí)行異步任務(wù)的能力。但它的最大問(wèn)題就是如果其中某個(gè)任務(wù)出現(xiàn)異常(reject),所有任務(wù)都會(huì)掛掉,Promise直接進(jìn)入 reject  狀態(tài)。

想象這個(gè)場(chǎng)景:你的頁(yè)面有三個(gè)區(qū)域,分別對(duì)應(yīng)三個(gè)獨(dú)立的接口數(shù)據(jù),使用 Promise.all 來(lái)并發(fā)三個(gè)接口,如果其中任意一個(gè)接口服務(wù)異常,狀態(tài)是reject,這會(huì)導(dǎo)致頁(yè)面中該三個(gè)區(qū)域數(shù)據(jù)全都無(wú)法渲染出來(lái),因?yàn)槿魏?reject 都會(huì)進(jìn)入catch回調(diào), 很明顯,這是無(wú)法接受的,如下:

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

我們需要一種機(jī)制,如果并發(fā)任務(wù)中,無(wú)論一個(gè)任務(wù)正?;蛘弋惓?,都會(huì)返回對(duì)應(yīng)的的狀態(tài)(fulfilled 或者 rejected)與結(jié)果(業(yè)務(wù)value 或者 拒因 reason),在 then 里面通過(guò) filter 來(lái)過(guò)濾出想要的業(yè)務(wù)邏輯結(jié)果,這就能最大限度的保障業(yè)務(wù)當(dāng)前狀態(tài)的可訪問(wèn)性,而 Promise.allSettled 就是解決這問(wèn)題的。

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

二:可選鏈(Optional chaining)

可選鏈 可讓我們?cè)诓樵兙哂卸鄬蛹?jí)的對(duì)象時(shí),不再需要進(jìn)行冗余的各種前置校驗(yàn)。

日常開(kāi)發(fā)中,我們經(jīng)常會(huì)遇到這種查詢

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

又或是這種

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

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

用了 Optional Chaining ,上面代碼會(huì)變成

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

可選鏈中的 ? 表示如果問(wèn)號(hào)左邊表達(dá)式有值, 就會(huì)繼續(xù)查詢問(wèn)號(hào)后面的字段。根據(jù)上面可以看出,用可選鏈可以大量簡(jiǎn)化類似繁瑣的前置校驗(yàn)操作,而且更安全。

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

當(dāng)我們查詢某個(gè)屬性時(shí),經(jīng)常會(huì)遇到,如果沒(méi)有該屬性就會(huì)設(shè)置一個(gè)默認(rèn)的值。比如下面代碼中查詢玩家等級(jí)。

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

在JS中,空字符串、0 等,當(dāng)進(jìn)行邏輯操作符判時(shí),會(huì)自動(dòng)轉(zhuǎn)化為 false。在上面的代碼里,如果玩家等級(jí)本身就是 0 級(jí), 變量 level 就會(huì)被賦值 暫無(wú)等級(jí) 字符串,這是邏輯錯(cuò)誤。

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

來(lái)看看用空值合并運(yùn)算符如何處理

// {
//  "level": 0  
// }
var level = `${user.level}級(jí)` ?? '暫無(wú)等級(jí)';
// level -> '0級(jí)'

用空值合并運(yùn)算在邏輯正確的前提下,代碼更加簡(jiǎn)潔。

空值合并運(yùn)算符 與 可選鏈 相結(jié)合,可以很輕松處理多級(jí)查詢并賦予默認(rèn)值問(wèn)題。

var level = user.data?.level ?? '暫無(wú)等級(jí)';

四:dynamic-import

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

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

當(dāng)然,webpack目前已很好的支持了該特性。

五:globalThis

Javascript 在不同的環(huán)境獲取全局對(duì)象有不通的方式,node 中通過(guò) global, web中通過(guò) window, self 等,有些甚至通過(guò) this 獲取,但通過(guò) this 是及其危險(xiǎn)的,this 在 js 中異常復(fù)雜,它嚴(yán)重依賴當(dāng)前的執(zhí)行上下文,這些無(wú)疑增加了獲取全局對(duì)象的復(fù)雜性。

過(guò)去獲取全局對(duì)象,可通過(guò)一個(gè)全局函數(shù)

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 目的就是提供一種標(biāo)準(zhǔn)化方式訪問(wèn)全局對(duì)象,有了 globalThis 后,你可以在任意上下文,任意時(shí)刻都能獲取到全局對(duì)象。

六:BigInt

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

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

num = num + 1; // -> 9007199254740992

// 再次加 +1 后無(wú)法正常運(yùn)算
num = num + 1; // -> 9007199254740992

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

為解決此問(wèn)題,ES2020提供一種新的數(shù)據(jù)類型:BigInt。

使用 BigInt 有兩種方式:

在整數(shù)字面量后面加n。

var bigIntNum = 9007199254740993n;

使用 BigInt 函數(shù)。

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

通過(guò) BigInt, 我們可以安全的進(jìn)行大數(shù)整型計(jì)算。

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

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

注意:

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

typeof 9007199254740993n; // -> 'bigint'

盡可能避免通過(guò)調(diào)用函數(shù) BigInt 方式來(lái)實(shí)例化超大整型。因?yàn)閰?shù)的字面量實(shí)際也是 Number 類型的一次實(shí)例化,超出安全范圍的數(shù)字,可能會(huì)引起精度丟失。

七: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>"]

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

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

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

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

如果獲取到全局所有匹配項(xiàng),包括子項(xiàng)呢?

ES2020提供了一種簡(jiǎn)易的方式:String.prototype.matchAll, 該方法會(huì)返回一個(gè)迭代器。

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/

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

最新評(píng)論