<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          ES11新增的這9個(gè)新特性,你都掌握了嗎?

          共 4322字,需瀏覽 9分鐘

           ·

          2020-12-31 09:29

          ECMAScript 2020 是 ECMAScript 語(yǔ)言規(guī)范的第11版。自1997年出版第一版以來(lái),ECMAScript 已發(fā)展成為世界上使用最廣泛的通用編程語(yǔ)言之一。

          ES2020(ES11) 引入了以下新特性:

          • StringmatchAll 方法

          • 動(dòng)態(tài)導(dǎo)入語(yǔ)句 import()

          • import.meta

          • export * as ns from 'module'

          • Promise.allSettled

          • 一種新的數(shù)據(jù)類型:BigInt

          • GlobalThis

          • Nullish coalescing Operator

          • Optional Chaining

          matchAll

          matchAll() 方法返回一個(gè)包含所有匹配正則表達(dá)式的結(jié)果的迭代器。使用 for...of 遍歷或者使用 操作符 ... Array.from 將其轉(zhuǎn)換成數(shù)組。

          const?reg?=?/[0-3]/g;
          const?data?=?'2020';?
          console.log(data.matchAll(reg));//data.matchAll?的返回值是一個(gè)迭代器
          console.log([...data.matchAll(reg)]);
          /**
          ?*?0:?["2",?index:?0,?input:?"2020",?groups:?undefined]
          ?*?1:?["0",?index:?1,?input:?"2020",?groups:?undefined]
          ?*?2:?["2",?index:?2,?input:?"2020",?groups:?undefined]
          ?*?3:?["0",?index:?3,?input:?"2020",?groups:?undefined]
          ?*/

          Dynamic import

          標(biāo)準(zhǔn)用法的 import 導(dǎo)入的模塊是靜態(tài)的,會(huì)使所有被導(dǎo)入的模塊,在加載時(shí)就被編譯(無(wú)法做到按需編譯,降低首頁(yè)加載速度)。有些場(chǎng)景中,你可能希望根據(jù)條件導(dǎo)入模塊或者按需導(dǎo)入模塊,這時(shí)你可以使用動(dòng)態(tài)導(dǎo)入代替靜態(tài)導(dǎo)入。

          import() 之前,當(dāng)我們需要根據(jù)條件導(dǎo)入模塊時(shí),不得不使用 require()

          如:

          if(XXX)?{
          ????const?menu?=?require('./menu');
          }

          如今可以替換為:

          if(XXX)?{
          ????const?menu?=?import('./menu');
          }

          @babel/preset-env 已經(jīng)包含了 @babel/plugin-syntax-dynamic-import,因此如果要使用 import() 語(yǔ)法,只需要配置 @babel/preset-env 即可。

          提示: 請(qǐng)不要濫用動(dòng)態(tài)導(dǎo)入(只有在必要情況下采用)。靜態(tài)框架能更好的初始化依賴,而且更有利于靜態(tài)分析工具和 tree shaking 發(fā)揮作用。

          另外,import() 返回的是一個(gè) promise 對(duì)象。例如:

          //menu.js
          export?default?{
          ????menu:?'menu'
          }
          //index.js
          if(true)?{
          ????let?menu?=?import('./menu');
          ????console.log(menu);?//Promise?{
          ????menu.then(data?=>?console.log(data));//Module?{default:?{menu:?"menu"},?__esModule:?true,?Symbol(Symbol.toStringTag):?"Module"}
          }?else?{

          }

          import.meta

          import.meta 會(huì)返回一個(gè)對(duì)象,有一個(gè) url 屬性,返回當(dāng)前模塊的url路徑,只能在模塊內(nèi)部使用。

          <script?src='./main.js'?type="module">script>
          //main.js
          console.log(import.meta);?//{url:?"http://localhost:8080/main.js"} PS:使用了 http-server 啟動(dòng)

          因?yàn)?import.meta 必須要在模塊內(nèi)部使用,如果不加 type="module",控制臺(tái)會(huì)報(bào)錯(cuò):Cannot use 'import.meta' outside a module

          最開始測(cè)試時(shí),我是在 React 的項(xiàng)目中測(cè)試的,僅配置了 @babel/preset-env@babel/preset-react 預(yù)設(shè),使用 import.meta 時(shí),會(huì)報(bào)錯(cuò)如下:

          安裝 @open-wc/webpack-import-meta-loader,修改 webpack 的配置,可以正常運(yùn)行。

          module:?{
          ????rules:?[
          ????????{
          ????????????test:?/\.js$/,
          ????????????use:?[
          ????????????????require.resolve('@open-wc/webpack-import-meta-loader'),
          ????????????????{
          ????????????????????loader:?'babel-loader',
          ????????????????????options:?{
          ????????????????????????presets:?[
          ????????????????????????????"@babel/preset-env",
          ????????????????????????????"@babel/preset-react"
          ????????????????????????]
          ????????????????????},
          ????????????????}
          ????????????]
          ????????}
          ????]
          }

          效果如下:

          //src/index.js
          import?React?from?'react';
          console.log(import.meta);//{index.js:38?{url:?"http://127.0.0.1:3000/src/index.js"}}

          export * as ns from 'module'

          ES2020新增了 export * as XX from 'module',和 import * as XX from 'module'

          //menu.js
          export?*?as?ns?from?'./info';

          可以理解為是將下面兩條語(yǔ)句合并為一句:

          import?*?as?ns?from?'./info';
          export?{?ns?};

          不過(guò)需要注意的是 export * as ns from './info' 并不會(huì)真的將導(dǎo)入模塊,因此在該模塊(menu.js)中,我們是獲取不到 ns 的。

          Promise.allSettled

          Promise.all 或者 Promise.race 有的時(shí)候并不能滿足我們的需求。比如,我們需要在所有的 promise 都結(jié)束的時(shí)候做一些操作,而并不在乎它們是成功還是失敗。在沒有 Promise.allSettled 之前,我們需要自己去寫實(shí)現(xiàn)。

          Promise.allSettled() 方法返回一個(gè)在所有給定的 promise 都已經(jīng) fulfilledrejected 后的 promise ,并帶有一個(gè)對(duì)象數(shù)組,每個(gè)對(duì)象表示對(duì)應(yīng)的 promise 結(jié)果。

          const?promise1?=?Promise.resolve(100);
          const?promise2?=?new?Promise((resolve,?reject)?=>?setTimeout(reject,?100,?'info'));
          const?promise3?=?new?Promise((resolve,?reject)?=>?setTimeout(resolve,?200,?'name'))

          Promise.allSettled([promise1,?promise2,?promise3]).
          ????then((results)?=>?console.log(result));
          /*?
          ????[
          ????????{?status:?'fulfilled',?value:?100?},
          ????????{?status:?'rejected',?reason:?'info'?},
          ????????{?status:?'fulfilled',?value:?'name'?}
          ????]
          */

          可以看到,Promise.allSettled() 的成功的結(jié)果是一個(gè)數(shù)組,該數(shù)組的每一項(xiàng)是一個(gè)對(duì)象,每個(gè)對(duì)象都有一個(gè) status 屬性,值為 fulfilledrejected,如果status 的值是 fulfilled,那么該對(duì)象還有一個(gè) value 屬性,其屬性值是對(duì)應(yīng)的 promise 成功的結(jié)果;如果 status 的值是 rejected,那么該對(duì)象有一個(gè) reason 屬性,其屬性值是對(duì)應(yīng)的 promise 失敗的原因。

          BigInt

          BigInt 是一種數(shù)字類型的數(shù)據(jù),它可以表示任意精度格式的整數(shù)。在此之前,JS 中安全的最大數(shù)字是 9009199254740991,即2^53-1,在控制臺(tái)中輸入 Number.MAX_SAFE_INTEGER 即可查看。超過(guò)這個(gè)值,JS 沒有辦法精確表示。另外,大于或等于2的1024次方的數(shù)值,JS 無(wú)法表示,會(huì)返回 Infinity

          BigInt 即解決了這兩個(gè)問(wèn)題。BigInt 只用來(lái)表示整數(shù),沒有位數(shù)的限制,任何位數(shù)的整數(shù)都可以精確表示。為了和 Number 類型進(jìn)行區(qū)分,BigInt 類型的數(shù)據(jù)必須添加后綴 n.

          //Number類型在超過(guò)9009199254740991后,計(jì)算結(jié)果即出現(xiàn)問(wèn)題
          const?num1?=?90091992547409910;
          console.log(num1?+?1);?//90091992547409900

          //BigInt?計(jì)算結(jié)果爭(zhēng)取
          const?num2?=?90091992547409910n;
          console.log(num2?+?1n);?//90091992547409911n
          //Number?類型不能表示大于?2?的?1024?次方的數(shù)值
          let?num3?=?9999;
          for(let?i?=?0;?i?10;?i++)?{
          ????num3?=?num3?*?num3;
          }
          console.log(num3);?//Infinity

          //BigInt?類型可以表示任意位數(shù)的整數(shù)
          let?num4?=?9999n;
          for(let?i?=?0n;?i?10n;?i++)?{
          ????num4?=?num4?*?num4;
          }
          console.log(num4);?//一串超級(jí)長(zhǎng)的數(shù)字,這里就不貼了

          我們還可以使用 BigInt 對(duì)象來(lái)初始化 BigInt 實(shí)例:

          console.log(BigInt(999));?// 999n 注意:沒有 new 關(guān)鍵字!!!

          需要說(shuō)明的是,BigIntNumber 是兩種數(shù)據(jù)類型,不能直接進(jìn)行四則運(yùn)算,不過(guò)可以進(jìn)行比較操作。

          console.log(99n?==?99);?//true
          console.log(99n?===?99);?//false?
          console.log(99n?+?1);//TypeError:?Cannot?mix?BigInt?and?other?types,?use?explicit?conversionss

          GlobalThis

          JS 中存在一個(gè)頂層對(duì)象,但是,頂層對(duì)象在各種實(shí)現(xiàn)里是不統(tǒng)一的。

          從不同的 JavaScript 環(huán)境中獲取全局對(duì)象需要不同的語(yǔ)句。在 Web 中,可以通過(guò) windowself 取到全局對(duì)象,但是在 Web Workers 中,只有 self 可以。在 Node.js 中,它們都無(wú)法獲取,必須使用 global

          globalThis 之前,我們這樣去獲取全局對(duì)象:

          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');
          };

          ES2020 中引入 globalThis 作為頂層對(duì)象,在任何環(huán)境下,都可以簡(jiǎn)單的通過(guò) globalThis 拿到頂層對(duì)象。

          Nullish coalescing Operator

          ES2020 新增了一個(gè)運(yùn)算符 ??。當(dāng)左側(cè)的操作數(shù)為 null 或者 undefined 時(shí),返回其右側(cè)操作數(shù),否則返回左側(cè)操作數(shù)。

          使用 || 操作符,當(dāng)左側(cè)的操作數(shù)為 0nullundefinedNaNfalse'' 時(shí),都會(huì)使用右側(cè)的操作數(shù)。如果使用 || 來(lái)為某些變量設(shè)置默認(rèn)值,可能會(huì)遇到意料之外的行為。

          例如:

          const?defaultValue?=?100;
          let?value?=?someValue?||?defaultValue;
          //當(dāng)?someValue?轉(zhuǎn)成?boolean?值為?false?時(shí),value?的值都是?defaultValue

          當(dāng) someValue 的值為 0 時(shí) ,我們其實(shí)期望 value 值為 0, 但是它卻被錯(cuò)誤的分配成了 100.

          ?? 操作符可以規(guī)避以上問(wèn)題,它只有在左操作數(shù)是 null 或者是 undefined 時(shí),才會(huì)返回右側(cè)操作數(shù)。

          const?defaultValue?=?100;
          let?value?=?someValue?||?defaultValue;//someValue?為?0?,value?的值是?0

          Optional Chaining

          可選鏈操作符 ?. 允許讀取位于連接對(duì)象鏈深處的屬性的值,而不必明確驗(yàn)證鏈中的每個(gè)引用是否有效。?. 操作符的功能類似于 . 鏈?zhǔn)讲僮鞣煌幵谟冢谝脼榭?nullish, 即 null 或者 undefined) 的情況下不會(huì)引起錯(cuò)誤,該表達(dá)式短路返回值是 undefined

          例如,我們要訪問(wèn) info 對(duì)象的 animalreptiletortoise。但是我們不確定 animal, reptile 是否存在,因此我們需要這樣寫:

          const?tortoise?=?info.animal?&&?info.animal.reptile?&&?info.animal.reptile.tortoise;

          因?yàn)?null.reptile 或 ?undefined.reptile 會(huì)拋出錯(cuò)誤:TypeError: Cannot read property 'reptile' of undefinedTypeError: Cannot read property 'reptile' of null,為了避免報(bào)錯(cuò),如果我們需要訪問(wèn)的屬性更深,那么這個(gè)這句代碼會(huì)越來(lái)越長(zhǎng)。

          而有了可選鏈操作符 ?.,我們?cè)谠L問(wèn) reptile 之前,不再需要校驗(yàn) info.animal 的值。同樣,在訪問(wèn) info.animal.reptile.tortoise 之前,也不需要校驗(yàn) info.animal.reptile 的值。

          上面的代碼簡(jiǎn)化為:

          const?tortoise?=?info.animal?.reptile?.tortoise;

          JS在嘗試訪問(wèn) info.animal.reptile 之前,會(huì)隱式檢查并確定 info.animal 的值不是 nullundefined,如果其值是 nullundefined,那么表達(dá)式短路計(jì)算直接返回 undefined

          可以看到可選鏈操作符 ?. 和空位合并操作符一樣,都是針對(duì)的 nullundefined 這兩個(gè)值。

          至此,ES2020 的新特性就都介紹完畢了,總得來(lái)講,新增內(nèi)容并不多,一杯咖啡的時(shí)間就可以掌握個(gè)大概,不過(guò)還是要經(jīng)常回顧,不然會(huì)很容易遺忘。

          參考資料

          • ecma-262

          • A Super Hacky Alternative to import.meta.url

          • import

          • export 與 import 的復(fù)合寫法

          • BigInt 數(shù)據(jù)類型

          • globalThis

          • globalThis對(duì)象

          關(guān)注數(shù):10億+?文章數(shù):10億+
          粉絲量:10億+?點(diǎn)擊量:10億+

          ?


          懸賞博主專區(qū)請(qǐng)掃描這里


          喜愛數(shù):?1億+?發(fā)帖數(shù):?1億+
          回帖數(shù):?1億+?結(jié)貼率:?99.9%


          —————END—————



          喜歡本文的朋友,歡迎關(guān)注公眾號(hào)?程序員哆啦A夢(mèng),收看更多精彩內(nèi)容

          點(diǎn)個(gè)[在看],是對(duì)小達(dá)最大的支持!


          如果覺得這篇文章還不錯(cuò),來(lái)個(gè)【分享、點(diǎn)贊、在看】三連吧,讓更多的人也看到~

          瀏覽 15
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  一级黄色欧美视频 | WWW.日韩AV电影 | 欧美黄色影片在线观看 | 夜色福利网| 日屄在线视频 |