ES2020新特性

可選鏈 (Optional chaining)

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

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

let name = user && user.info && user.info.name;

又或者是這種

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

如果在任何級(jí)別的對(duì)象中都有 undefined 或者 null 的嵌套對(duì)象着饥,如果不進(jìn)行檢查犀农,那么很容易命中 Uncaught TypeError: Cannot read property... 這種錯(cuò)誤,這很有可能讓你的程序崩潰宰掉。因此呵哨,我們必須檢查每個(gè)級(jí)別,以確保當(dāng)它遇到 undefined 或 null 對(duì)象時(shí)不會(huì)崩潰轨奄。

使用可選鏈運(yùn)算符孟害,只需要使用 ?. 來(lái)訪問嵌套對(duì)象。而且如果碰到 undefined 或 null 屬性挪拟,那么他只會(huì)返回 undefined挨务。

使用可選鏈,上面的代碼可改為:

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

可選鏈中的 ? 表示如果聞號(hào)左邊的表達(dá)式有值玉组,就會(huì)繼續(xù)查詢問好后面的字段

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

undefined 或 null 值所產(chǎn)生的另一個(gè)問題谎柄,如果我們想要的變量為 undefined 或 null,則必須給變量設(shè)置默認(rèn)值球切。例如:

const a = b || '暫無(wú)數(shù)據(jù)';

當(dāng)使用 || 運(yùn)算符將 b 賦值給 a 時(shí)谷誓,如果 b 被定義為 undefined,我們就必須設(shè)置一個(gè)默認(rèn)值吨凑。
運(yùn)算符 || 的問題在于捍歪,在 JS 中,所有類似于 0鸵钝、false 或空字符串之類的值糙臼,在進(jìn)行邏輯操作符判斷時(shí),都會(huì)自動(dòng)轉(zhuǎn)化為 false恩商,如果用戶輸入的本身就是 0变逃,a 也會(huì)被賦值為 暫無(wú)數(shù)據(jù),就會(huì)出現(xiàn)邏輯錯(cuò)誤怠堪。

為了解決這個(gè)問題揽乱,創(chuàng)建了 nullish 合并運(yùn)算符,用 ?? 表示粟矿。有了它凰棉,我們僅在第一項(xiàng)為 null 或 undefined 時(shí)設(shè)置默認(rèn)值。

使用無(wú)效的合并運(yùn)算符陌粹,以上表達(dá)式可改為:

const a = b ?? '暫無(wú)數(shù)據(jù)';

通過 # 給 class 添加私有變量

class Counter {
    #num = 10;
    increment() {
        this.#num ++;
    }
    getNum() {
        return this.#num;
    }
}
const counter = new Counter()
counter.increment()
console.log(counter.getNum())   // 11
console.log(counter.#num)   // SyntaxError

在 ES2020 中撒犀,通過 # 可以給 class 添加私有變量。在 class 的外部我們無(wú)法獲取該值。這樣就不需要使用閉包來(lái)隱藏不想暴露給外籍的私有變量或舞。

BigInt

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

let num = Number.MIN_SAFE_INTEGER;  // 9007199254740991

num += 1;   // 9007199254740992

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

// 兩個(gè)不同的值比較胆筒,返回 true
console.log(9007199254740992 === 9007199254740993); // true

為了解決這個(gè)問題,ES2020 提供了一種新的數(shù)據(jù)類型:BigInt魏宽。
使用 BigInt 有兩種方式:

  1. 在整數(shù)字面量后面加 n
    const bigIntNum = 9007199254740993n;
    
  2. 使用 BigInt 函數(shù)
    const bigIntNum = BigInt(9007199254740993)
    const anotherBigIntNum = BigInt('9007199254740995')
    
    通過 BigInt腐泻,可以安全地進(jìn)行大數(shù)整型計(jì)算
    const bigNumRet = 9007199254740993n + 9007199254740993n;
    bigNumRet.toString();   // "18014398509481986"
    

注意:

  • BigInt 是一種新的數(shù)據(jù)原始類型
    typeof 9007199254740993n; // 'bigint';
    
  • 盡可能避免通過調(diào)用函數(shù) BigInt 方式來(lái)實(shí)例化超大整型。因?yàn)閰?shù)的字面量實(shí)際也是 Number 類型的一次實(shí)例化队询,超出安全范圍的數(shù)字派桩,可能會(huì)引起精度丟失。

Promise.allSettled

Promise.all 缺陷

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

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

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

Promise.allSettled(iterable)

iterable:一個(gè)可迭代的對(duì)象镇匀,例如 Array,其中每個(gè)成員都是 Promise

返回一個(gè)在所有給定的 promise resolved 或者 rejected 的 promise袜啃,并帶有一個(gè)對(duì)象數(shù)組汗侵,每個(gè)對(duì)象表示對(duì)應(yīng)的 promise 結(jié)果。

Promise.allSettled([
    Promise.reject({ code: 500, message }),
    Promise.resolve({ code: 200, list: [] }),
    Promise.resolve({ code: 200, list: [] }),
]).then(res => {
    /*
        [
            { status: "rejected", reason: {...} },
            { status: "fulfilled", value: {...} },
            { status: "fulfilled", value: {...} },
        ]
    */
    // 過濾掉 reject 狀態(tài)群发,盡可能多的保證頁(yè)面區(qū)域數(shù)據(jù)渲染
    RenderContent(res.filter(item => {
        return item.status !== 'rejected';
    }));
})

dynamic-import

靜態(tài) import 和動(dòng)態(tài) import() 有各自的特點(diǎn)和使用場(chǎng)景晰韵。

static import 是沒有括號(hào)的,dynamic import() 是帶括號(hào)的熟妓。

用法區(qū)別:

// 有聲明提升雪猪,一般只放在頭部位置
static import: import xxx from 'xxx';
// 可以放在任何位置
dynamic import(): const xxx = import('xxx');

按需執(zhí)行邏輯資源都體現(xiàn)在某一個(gè)時(shí)間回調(diào)中去加載,為了首屏渲染速度更快滑蚯,很多時(shí)候都是按需加載。

el.onclick = () => {
    import('/example.js').then(module => {
        module.todo();
    }).catch(err => {
        // load error
    })
}

globalThis

JavaScript 在不同的環(huán)境獲取全局對(duì)象有不同的方式,node 中通過 global告材,web 中通過 window坤次、self 等,有些甚至通過 this 獲取斥赋,但是通過 this 是極其危險(xiǎn)的缰猴,this 在 js 中很依賴當(dāng)前的執(zhí)行上下文。

globalThis 提供了標(biāo)準(zhǔn)的方式去獲取不同環(huán)境下的全局對(duì)象疤剑。它不想 window 或者 self 這些屬性滑绒,而是確保可以再有無(wú)窗口的環(huán)境下都可以正常工作隘膘,不必?fù)?dān)心它的運(yùn)行環(huán)境疑故。

  • 過去獲取全局對(duì)象的方式,可通過一個(gè)全局函數(shù)
    const getGlobal = () => {
        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');
    }
    const globals = getGlobal();
    console.log(globals)
    
  • 使用 globalThis 獲取全局對(duì)象
    console.log(globalThis)
    
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末弯菊,一起剝皮案震驚了整個(gè)濱河市纵势,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌管钳,老刑警劉巖钦铁,帶你破解...
    沈念sama閱讀 216,496評(píng)論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異才漆,居然都是意外死亡牛曹,警方通過查閱死者的電腦和手機(jī)搪搏,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,407評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門志秃,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)攀细,“玉大人效扫,你說(shuō)我怎么就攤上這事今妄《瘢” “怎么了孽拷?”我有些...
    開封第一講書人閱讀 162,632評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵荠藤,是天一觀的道長(zhǎng)怀喉。 經(jīng)常有香客問我书妻,道長(zhǎng),這世上最難降的妖魔是什么躬拢? 我笑而不...
    開封第一講書人閱讀 58,180評(píng)論 1 292
  • 正文 為了忘掉前任躲履,我火速辦了婚禮,結(jié)果婚禮上聊闯,老公的妹妹穿的比我還像新娘工猜。我一直安慰自己,他們只是感情好菱蔬,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,198評(píng)論 6 388
  • 文/花漫 我一把揭開白布篷帅。 她就那樣靜靜地躺著史侣,像睡著了一般。 火紅的嫁衣襯著肌膚如雪魏身。 梳的紋絲不亂的頭發(fā)上惊橱,一...
    開封第一講書人閱讀 51,165評(píng)論 1 299
  • 那天,我揣著相機(jī)與錄音箭昵,去河邊找鬼税朴。 笑死,一個(gè)胖子當(dāng)著我的面吹牛家制,可吹牛的內(nèi)容都是我干的正林。 我是一名探鬼主播,決...
    沈念sama閱讀 40,052評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼颤殴,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼觅廓!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起诅病,我...
    開封第一講書人閱讀 38,910評(píng)論 0 274
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤哪亿,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后贤笆,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體蝇棉,經(jīng)...
    沈念sama閱讀 45,324評(píng)論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,542評(píng)論 2 332
  • 正文 我和宋清朗相戀三年芥永,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了篡殷。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,711評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡埋涧,死狀恐怖板辽,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情棘催,我是刑警寧澤劲弦,帶...
    沈念sama閱讀 35,424評(píng)論 5 343
  • 正文 年R本政府宣布,位于F島的核電站醇坝,受9級(jí)特大地震影響邑跪,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜呼猪,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,017評(píng)論 3 326
  • 文/蒙蒙 一画畅、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧宋距,春花似錦轴踱、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,668評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)诱篷。三九已至,卻和暖如春雳灵,著一層夾襖步出監(jiān)牢的瞬間兴蒸,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,823評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工细办, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人蕾殴。 一個(gè)月前我還...
    沈念sama閱讀 47,722評(píng)論 2 368
  • 正文 我出身青樓笑撞,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親钓觉。 傳聞我的和親對(duì)象是個(gè)殘疾皇子茴肥,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,611評(píng)論 2 353

推薦閱讀更多精彩內(nèi)容

  • [TOC] 參考阮一峰的ECMAScript 6 入門參考深入淺出ES6 let和const let和const都...
    郭子web閱讀 1,781評(píng)論 0 1
  • 第一章:塊級(jí)作用域綁定 塊級(jí)聲明 1.var聲明及變量提升機(jī)制:在函數(shù)作用域或者全局作用域中通過關(guān)鍵字var聲明的...
    BeADre_wang閱讀 834評(píng)論 0 0
  • https://kangax.github.io/compat-table/es6/ 查詢各個(gè)瀏覽器對(duì)ES的支持:...
    肉桂猿閱讀 162評(píng)論 0 1
  • 語(yǔ)句 JavaScript程序的執(zhí)行單位為行(line),也就是一行一行地執(zhí)行荡灾。一般情況下瓤狐,每一行就是一個(gè)語(yǔ)句。 ...
    米塔塔閱讀 454評(píng)論 1 10
  • JavaScript語(yǔ)言精粹 前言 約定:=> 表示參考相關(guān)文章或書籍; JS是JavaScript的縮寫批幌。 本書...
    微笑的AK47閱讀 580評(píng)論 0 3