日韩无码专区无码一级三级片|91人人爱网站中日韩无码电影|厨房大战丰满熟妇|AV高清无码在线免费观看|另类AV日韩少妇熟女|中文日本大黄一级黄色片|色情在线视频免费|亚洲成人特黄a片|黄片wwwav色图欧美|欧亚乱色一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時(shí)間:8:30-17:00
你可能遇到了下面的問(wèn)題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營(yíng)銷解決方案
盤點(diǎn)ES7、ES8、ES9、ES10的新特性

【稿件】

為高邑等地區(qū)用戶提供了全套網(wǎng)頁(yè)設(shè)計(jì)制作服務(wù),及高邑網(wǎng)站建設(shè)行業(yè)解決方案。主營(yíng)業(yè)務(wù)為成都網(wǎng)站設(shè)計(jì)、成都網(wǎng)站制作、高邑網(wǎng)站設(shè)計(jì),以傳統(tǒng)方式定制建設(shè)網(wǎng)站,并提供域名空間備案等一條龍服務(wù),秉承以專業(yè)、用心的態(tài)度為用戶提供真誠(chéng)的服務(wù)。我們深信只要達(dá)到每一位用戶的要求,就會(huì)得到認(rèn)可,從而選擇與我們長(zhǎng)期合作。這樣,我們也可以走得更遠(yuǎn)!

前言

從 ECMAScript 2016(ES7)開(kāi)始,版本發(fā)布變得更加頻繁,每年發(fā)布一個(gè)新版本,好在每次版本的更新內(nèi)容并不多,本文會(huì)細(xì)說(shuō)這些新特性,盡可能和舊知識(shí)相關(guān)聯(lián),幫你迅速上手這些特性。

ES7新特性

1.Array.prototype.includes()方法

在 ES6 中我們有 String.prototype.includes() 可以查詢給定字符串是否包含一個(gè)字符,而在 ES7 中,我們?cè)跀?shù)組中也可以用 Array.prototype.includes 方法來(lái)判斷一個(gè)數(shù)組是否包含一個(gè)指定的值,根據(jù)情況,如果包含則返回true,否則返回false。

 
 
 
 
  1. const arr = [1, 3, 5, 2, '8', NaN, -0] 
  2. arr.includes(1) // true 
  3. arr.includes(1, 2) // false 該方法的第二個(gè)參數(shù)表示搜索的起始位置,默認(rèn)為0 
  4. arr.includes('1') // false 
  5. arr.includes(NaN) // true 
  6. arr.includes(+0) // true 

在ES7之前想判斷數(shù)組中是否包含一個(gè)元素,有如下兩種方法,但都不如includes來(lái)得直觀:

  • indexOf()

indexOf()方法返回在數(shù)組中可以找到一個(gè)給定元素的第一個(gè)索引,如果不存在,則返回-1。

 
 
 
 
  1. if (arr.indexOf(el) !== -1) { 
  2.   // ... 

不過(guò)這種方法有兩個(gè)缺點(diǎn),一是不夠語(yǔ)義化,要先找到參數(shù)值的第一個(gè)出現(xiàn)位置,所以要去比較是否不等于-1,表達(dá)起來(lái)不夠直觀。二是,它內(nèi)部使用嚴(yán)格相等運(yùn)算符(===)進(jìn)行判斷,這會(huì)導(dǎo)致對(duì)NaN的誤判。

 
 
 
 
  1. [NaN].indexOf(NaN)// -1 
  • find() 和 findIndex()

數(shù)組實(shí)例的find方法,用于找出第一個(gè)符合條件的數(shù)組成員。另外,這兩個(gè)方法都可以發(fā)現(xiàn)NaN,彌補(bǔ)了數(shù)組的indexOf方法的不足。

 
 
 
 
  1. [1, 4, -5, 10].find((n) => n < 0) // -5 
  2. [1, 5, 10, 15].findIndex(function(value) { 
  3.   return value > 9; 
  4. }) // 2 
  5. [NaN].findIndex(y => Object.is(NaN, y)) // 0 

Array.prototype.includes()的支持情況:

2.求冪運(yùn)算符**

在ES7中引入了指數(shù)運(yùn)算符,具有與Math.pow()等效的計(jì)算結(jié)果

 
 
 
 
  1. console.log(2**10);// 輸出1024zhicc 
  2. console.log(Math.pow(2, 10)) // 輸出1024 

求冪運(yùn)算符的支持情況:

ES8新特性

1.Async/Await

我們都知道使用Promise能很好地解決回調(diào)地獄的問(wèn)題,但如果處理流程比較復(fù)雜的話,那么整段代碼將充斥著then,語(yǔ)義化不明顯,代碼不能很好地表示執(zhí)行流程,那有沒(méi)有比Promise更優(yōu)雅的異步方式呢?

假如有這樣一個(gè)使用場(chǎng)景:需要先請(qǐng)求a鏈接,等返回信息之后,再請(qǐng)求b鏈接的另外一個(gè)資源。下面代碼展示的是使用fetch來(lái)實(shí)現(xiàn)這樣的需求,fetch被定義在window對(duì)象中,它返回的是一個(gè)Promise對(duì)象

 
 
 
 
  1. fetch('https://blog.csdn.net/') 
  2.   .then(response => { 
  3.     console.log(response) 
  4.     return fetch('https://juejin.im/') 
  5.   }) 
  6.   .then(response => { 
  7.     console.log(response) 
  8.   }) 
  9.   .catch(error => { 
  10.     console.log(error) 
  11.   }) 

雖然上述代碼可以實(shí)現(xiàn)這個(gè)需求,但語(yǔ)義化不明顯,代碼不能很好地表示執(zhí)行流程?;谶@個(gè)原因,ES8引入了async/await,這是JavaScript異步編程的一個(gè)重大改進(jìn),提供了在不阻塞主線程的情況下使用同步代碼實(shí)現(xiàn)異步訪問(wèn)資源的能力,并且使得代碼邏輯更加清晰。

 
 
 
 
  1. async function foo () { 
  2.   try { 
  3.     let response1 = await fetch('https://blog.csdn.net/') 
  4.     console.log(response1) 
  5.     let response2 = await fetch('https://juejin.im/') 
  6.     console.log(response2) 
  7.   } catch (err) { 
  8.     console.error(err) 
  9.   } 
  10. foo() 

通過(guò)上面代碼,你會(huì)發(fā)現(xiàn)整個(gè)異步處理的邏輯都是使用同步代碼的方式來(lái)實(shí)現(xiàn)的,而且還支持try catch來(lái)捕獲異常,這感覺(jué)就在寫同步代碼,所以是非常符合人的線性思維的。需要強(qiáng)調(diào)的是,await 不可以脫離 async 單獨(dú)使用,await 后面一定是Promise 對(duì)象,如果不是會(huì)自動(dòng)包裝成Promise對(duì)象。

根據(jù)MDN定義,async是一個(gè)通過(guò)異步執(zhí)行并隱式返回Promise作為結(jié)果的函數(shù)。

 
 
 
 
  1. async function foo () { 
  2.   return '浪里行舟' 
  3. foo().then(val => { 
  4.   console.log(val) // 浪里行舟 
  5. }) 

上述代碼,我們可以看到調(diào)用async 聲明的foo 函數(shù)返回了一個(gè)Promise對(duì)象,等價(jià)于下面代碼:

 
 
 
 
  1. async function foo () { 
  2.   return Promise.resolve('浪里行舟') 
  3. foo().then(val => { 
  4.   console.log(val) // 浪里行舟 
  5. }) 

Async/Await的支持情況:

2.Object.values(),Object.entries()

ES5 引入了Object.keys方法,返回一個(gè)數(shù)組,成員是參數(shù)對(duì)象自身的(不含繼承的)所有可遍歷(enumerable)屬性的鍵名。ES8引入了跟Object.keys配套的Object.values和Object.entries,作為遍歷一個(gè)對(duì)象的補(bǔ)充手段,供for...of循環(huán)使用。

Object.values方法返回一個(gè)數(shù)組,成員是參數(shù)對(duì)象自身的(不含繼承的)所有可遍歷(enumerable)屬性的鍵值。

 
 
 
 
  1. const obj = { foo: 'bar', baz: 42 }; 
  2. Object.values(obj) // ["bar", 42] 
  3. const obj = { 100: 'a', 2: 'b', 7: 'c' }; 
  4. Object.values(obj) // ["b", "c", "a"] 

需要注意的是,如果屬性名為數(shù)值的屬性,是按照數(shù)值大小,從小到大遍歷的,因此返回的順序是b、c、a。

Object.entries()方法返回一個(gè)數(shù)組,成員是參數(shù)對(duì)象自身的(不含繼承的)所有可遍歷(enumerable)屬性的鍵值對(duì)數(shù)組。這個(gè)特性我們后面介紹ES10的Object.fromEntries()還會(huì)再提到。

 
 
 
 
  1. const obj = { foo: 'bar', baz: 42 }; 
  2. Object.entries(obj) // [ ["foo", "bar"], ["baz", 42] ] 
  3. const obj = { 10: 'xxx', 1: 'yyy', 3: 'zzz' }; 
  4. Object.entries(obj); //[['1', 'yyy'], ['3', 'zzz'], ['10': 'xxx']]

Object.values()與Object.entries()兼容性一致,下面以O(shè)bject.values()為例:

3.String padding

在ES8中String 新增了兩個(gè)實(shí)例函數(shù) String.prototype.padStart 和 String.prototype.padEnd,允許將空字符串或其他字符串添加到原始字符串的開(kāi)頭或結(jié)尾。我們先看下使用語(yǔ)法:

 
 
 
 
  1. String.padStart(targetLength,[padString]) 
  • targetLength(必填):當(dāng)前字符串需要填充到的目標(biāo)長(zhǎng)度。如果這個(gè)數(shù)值小于當(dāng)前字符串的長(zhǎng)度,則返回當(dāng)前字符串本身。

  • padString(可選):填充字符串。如果字符串太長(zhǎng),使填充后的字符串長(zhǎng)度超過(guò)了目標(biāo)長(zhǎng)度,則只保留最左側(cè)的部分,其他部分會(huì)被截?cái)?,此參?shù)的缺省值為 " "。

 
 
 
 
  1. 'x'.padStart(4, 'ab') // 'abax' 
  2. 'x'.padEnd(5, 'ab') // 'xabab' 

有時(shí)候我們處理日期、金額的時(shí)候經(jīng)常要格式化,這個(gè)特性就派上用場(chǎng):

 
 
 
 
  1. '12'.padStart(10, 'YYYY-MM-DD') // "YYYY-MM-12" 
  2. '09-12'.padStart(10, 'YYYY-MM-DD') // "YYYY-09-12" 

String padding的支持情況:

4.Object.getOwnPropertyDescriptors()

ES5 的Object.getOwnPropertyDescriptor()方法會(huì)返回某個(gè)對(duì)象屬性的描述對(duì)象(descriptor)。ES8 引入了Object.getOwnPropertyDescriptors()方法,返回指定對(duì)象所有自身屬性(非繼承屬性)的描述對(duì)象。

 
 
 
 
  1. const obj = { 
  2.   name: '浪里行舟', 
  3.   get bar () { 
  4.     return 'abc' 
  5.   } 
  6. console.log(Object.getOwnPropertyDescriptors(obj)) 

得到如下結(jié)果:

該方法的引入目的,主要是為了解決Object.assign()無(wú)法正確拷貝get屬性和set屬性的問(wèn)題。我們來(lái)看個(gè)例子:

 
 
 
 
  1. const source = { 
  2.   set foo (value) { 
  3.     console.log(value) 
  4.   }, 
  5.   get bar () { 
  6.     return '浪里行舟' 
  7.   } 
  8. const target1 = {} 
  9. Object.assign(target1, source) 
  10. console.log(Object.getOwnPropertyDescriptor(target1, 'foo')) 

返回如下結(jié)果:

上面代碼中,source對(duì)象的foo屬性的值是一個(gè)賦值函數(shù),Object.assign方法將這個(gè)屬性拷貝給target1對(duì)象,結(jié)果該屬性的值變成了undefined。這是因?yàn)?strong>Object.assign方法總是拷貝一個(gè)屬性的值,而不會(huì)拷貝它背后的賦值方法或取值方法。

這時(shí),Object.getOwnPropertyDescriptors()方法配合Object.defineProperties()方法,就可以實(shí)現(xiàn)正確拷貝。

 
 
 
 
  1. const source = { 
  2.   set foo (value) { 
  3.     console.log(value) 
  4.   }, 
  5.   get bar () { 
  6.     return '浪里行舟' 
  7.   } 
  8. const target2 = {} 
  9. Object.defineProperties(target2, Object.getOwnPropertyDescriptors(source)) 
  10. console.log(Object.getOwnPropertyDescriptor(target2, 'foo')) 

返回如下結(jié)果:

Object.getOwnPropertyDescriptors()的支持情況:

 

ES9新特性

1.for await of

for of方法能夠遍歷具有Symbol.iterator接口的同步迭代器數(shù)據(jù),但是不能遍歷異步迭代器。 ES9新增的for await of可以用來(lái)遍歷具有Symbol.asyncIterator方法的數(shù)據(jù)結(jié)構(gòu),也就是異步迭代器,且會(huì)等待前一個(gè)成員的狀態(tài)改變后才會(huì)遍歷到下一個(gè)成員,相當(dāng)于async函數(shù)內(nèi)部的await。現(xiàn)在我們有三個(gè)異步任務(wù),想要實(shí)現(xiàn)依次輸出結(jié)果,該如何實(shí)現(xiàn)呢?

 
 
 
 
  1. // for of遍歷 
  2. function Gen (time) { 
  3.   return new Promise(function (resolve, reject) { 
  4.     setTimeout(function () { 
  5.       resolve(time) 
  6.     }, time) 
  7.   }) 
  8. async function test () { 
  9.   let arr = [Gen(2000), Gen(100), Gen(3000)] 
  10.   for (let item of arr) { 
  11.     console.log(Date.now(), item.then(console.log)) 
  12.   } 
  13. test() 

得到如下結(jié)果:

上述代碼證實(shí)了for of方法不能遍歷異步迭代器,得到的結(jié)果并不是我們所期待的,于是for await of就粉墨登場(chǎng)啦!

 
 
 
 
  1. function Gen (time) { 
  2.   return new Promise(function (resolve, reject) { 
  3.     setTimeout(function () { 
  4.       resolve(time) 
  5.     }, time) 
  6.   }) 
  7. async function test () { 
  8.   let arr = [Gen(2000), Gen(100), Gen(3000)] 
  9.   for await (let item of arr) { 
  10.     console.log(Date.now(), item) 
  11.   } 
  12. test() 
  13. // 1575536194608 2000 
  14. // 1575536194608 100 
  15. // 1575536195608 3000 

使用for await of遍歷時(shí),會(huì)等待前一個(gè)Promise對(duì)象的狀態(tài)改變后,再遍歷到下一個(gè)成員。

異步迭代器的支持情況: 

2.Object Rest Spread

ES6中添加的最有意思的特性之一是spread操作符。你不僅可以用它替換cancat()和slice()方法,使數(shù)組的操作(復(fù)制、合并)更加簡(jiǎn)單,還可以在數(shù)組必須以拆解的方式作為函數(shù)參數(shù)的情況下,spread操作符也很實(shí)用。

 
 
 
 
  1. const arr1 = [10, 20, 30]; 
  2. const copy = [...arr1]; // 復(fù)制 
  3. console.log(copy);    // [10, 20, 30] 
  4. const arr2 = [40, 50]; 
  5. const merge = [...arr1, ...arr2]; // 合并 
  6. console.log(merge);    // [10, 20, 30, 40, 50] 
  7. console.log(Math.max(...arr));    // 30 拆解 

ES9通過(guò)向?qū)ο笪谋咎砑訑U(kuò)展屬性進(jìn)一步擴(kuò)展了這種語(yǔ)法。他可以將一個(gè)對(duì)象的屬性拷貝到另一個(gè)對(duì)象上,參考以下情形:

 
 
 
 
  1. const input = { 
  2.   a: 1, 
  3.   b: 2, 
  4.   c: 1 
  5. const output = { 
  6.   ...input, 
  7.   c: 3 
  8. console.log(output) // {a: 1, b: 2, c: 3} 

上面代碼可以把 input 對(duì)象的數(shù)據(jù)都添加到 output 對(duì)象中,需要注意的是,如果存在相同的屬性名,只有最后一個(gè)會(huì)生效。

 
 
 
 
  1. const input = { 
  2.   a: 1, 
  3.   b: 2 
  4. const output = { 
  5.   ...input, 
  6.   c: 3 
  7. input.a='浪里行舟' 
  8. console.log(input,output) // {a: "浪里行舟", b: 2} {a: 1, b: 2, c: 3} 

上面例子中,修改input對(duì)象中的值,output并沒(méi)有改變,說(shuō)明擴(kuò)展運(yùn)算符拷貝一個(gè)對(duì)象(類似這樣obj2 = {...obj1}),實(shí)現(xiàn)只是一個(gè)對(duì)象的淺拷貝。值得注意的是,如果屬性的值是一個(gè)對(duì)象的話,該對(duì)象的引用會(huì)被拷貝:

 
 
 
 
  1. const obj = {x: {y: 10}}; 
  2. const copy1 = {...obj};     
  3. const copy2 = {...obj};  
  4. obj.x.y='浪里行舟' 
  5. console.log(copy1,copy2) // x: {y: "浪里行舟"} x: {y: "浪里行舟"} 
  6. console.log(copy1.x === copy2.x);    // → true 

copy1.x 和 copy2.x 指向同一個(gè)對(duì)象的引用,所以他們嚴(yán)格相等。

我們?cè)賮?lái)看下 Object rest 的示例:

 
 
 
 
  1. const input = { 
  2.   a: 1, 
  3.   b: 2, 
  4.   c: 3 
  5. let { a, ...rest } = input 
  6. console.log(a, rest) // 1 {b: 2, c: 3} 

當(dāng)對(duì)象 key-value 不確定的時(shí)候,把必選的 key 賦值給變量,用一個(gè)變量收斂其他可選的 key 數(shù)據(jù),這在之前是做不到的。注意,rest屬性必須始終出現(xiàn)在對(duì)象的末尾,否則將拋出錯(cuò)誤。

Rest與Spread兼容性一致,下列以spread為例:

3.Promise.prototype.finally()

Promise.prototype.finally() 方法返回一個(gè)Promise,在promise執(zhí)行結(jié)束時(shí),無(wú)論結(jié)果是fulfilled或者是rejected,在執(zhí)行then()和catch()后,都會(huì)執(zhí)行finally指定的回調(diào)函數(shù)。

 
 
 
 
  1. fetch('https://www.google.com') 
  2.   .then((response) => { 
  3.     console.log(response.status); 
  4.   }) 
  5.   .catch((error) => {  
  6.     console.log(error); 
  7.   }) 
  8.   .finally(() => {  
  9.     document.querySelector('#spinner').style.display = 'none'; 
  10.   }); 

無(wú)論操作是否成功,當(dāng)您需要在操作完成后進(jìn)行一些清理時(shí),finally()方法就派上用場(chǎng)了。這為指定執(zhí)行完promise后,無(wú)論結(jié)果是fulfilled還是rejected都需要執(zhí)行的代碼提供了一種方式,避免同樣的語(yǔ)句需要在then()和catch()中各寫一次的情況。

Promise.prototype.finally()的支持情況:

4.新的正則表達(dá)式特性

ES9為正則表達(dá)式添加了四個(gè)新特性,進(jìn)一步提高了JavaScript的字符串處理能力。這些特點(diǎn)如下:

  • s (dotAll) 標(biāo)志

  • 命名捕獲組

  • Lookbehind 后行斷言

  • Unicode屬性轉(zhuǎn)義

(1)s(dotAll)flag

正則表達(dá)式中,點(diǎn)(.)是一個(gè)特殊字符,代表任意的單個(gè)字符,但是有兩個(gè)例外。一個(gè)是四個(gè)字節(jié)的 UTF-16 字符,這個(gè)可以用u修飾符解決;另一個(gè)是行終止符,如換行符(\n)或回車符(\r),這個(gè)可以通過(guò)ES9的s(dotAll)flag,在原正則表達(dá)式基礎(chǔ)上添加s表示:

 
 
 
 
  1. console.log(/foo.bar/.test('foo\nbar')) // false 
  2. console.log(/foo.bar/s.test('foo\nbar')) // true 

那如何判斷當(dāng)前正則是否使用了 dotAll 模式呢?

 
 
 
 
  1. const re = /foo.bar/s // Or, `const re = new RegExp('foo.bar', 's');`. 
  2. console.log(re.test('foo\nbar')) // true 
  3. console.log(re.dotAll) // true 
  4. console.log(re.flags) // 's' 

(2)命名捕獲組

在一些正則表達(dá)式模式中,使用數(shù)字進(jìn)行匹配可能會(huì)令人混淆。例如,使用正則表達(dá)式/(\d{4})-(\d{2})-(\d{2})/來(lái)匹配日期。因?yàn)槊朗接⒄Z(yǔ)中的日期表示法和英式英語(yǔ)中的日期表示法不同,所以很難區(qū)分哪一組表示日期,哪一組表示月份:

 
 
 
 
  1. const re = /(\d{4})-(\d{2})-(\d{2})/; 
  2. const match= re.exec('2019-01-01'); 
  3. console.log(match[0]);    // → 2019-01-01 
  4. console.log(match[1]);    // → 2019 
  5. console.log(match[2]);    // → 01 
  6. console.log(match[3]);    // → 01 

ES9引入了命名捕獲組,允許為每一個(gè)組匹配指定一個(gè)名字,既便于閱讀代碼,又便于引用。

 
 
 
 
  1. const re = /(?\d{4})-(?\d{2})-(?\d{2})/; 
  2. const match = re.exec('2019-01-01'); 
  3. console.log(match.groups);          // → {year: "2019", month: "01", day: "01"} 
  4. console.log(match.groups.year);     // → 2019 
  5. console.log(match.groups.month);    // → 01 
  6. console.log(match.groups.day);      // → 01 

上面代碼中,“命名捕獲組”在圓括號(hào)內(nèi)部,模式的頭部添加“問(wèn)號(hào) + 尖括號(hào) + 組名”(?),然后就可以在exec方法返回結(jié)果的groups屬性上引用該組名。

命名捕獲組也可以使用在replace()方法中,例如將日期轉(zhuǎn)換為美國(guó)的 MM-DD-YYYY 格式:

 
 
 
 
  1. const re = /(?\d{4})-(?\d{2})-(?\d{2})/ 
  2. const usDate = '2018-04-30'.replace(re, '$-$-$') 
  3. console.log(usDate) // 04-30-2018 

(3)Lookbehind 后行斷言

JavaScript 語(yǔ)言的正則表達(dá)式,只支持先行斷言,不支持后行斷言,先行斷言我們可以簡(jiǎn)單理解為"先遇到一個(gè)條件,再判斷后面是否滿足",如下面例子:

 
 
 
 
  1. let test = 'hello world' 
  2. console.log(test.match(/hello(?=\sworld)/)) 
  3. // ["hello", index: 0, input: "hello world", groups: undefined] 

但有時(shí)我們想判斷前面是 world 的 hello,這個(gè)代碼是實(shí)現(xiàn)不了的。在 ES9 就支持這個(gè)后行斷言了:

 
 
 
 
  1. let test = 'world hello' 
  2. console.log(test.match(/(?<=world\s)hello/)) 
  3. // ["hello", index: 6, input: "world hello", groups: undefined] 

(?<…)是后行斷言的符號(hào),(?..)是先行斷言的符號(hào),然后結(jié)合 =(等于)、!(不等)、\1(捕獲匹配)。

(4)Unicode屬性轉(zhuǎn)義

ES2018 引入了一種新的類的寫法\p{...}和\P{...},允許正則表達(dá)式匹配符合 Unicode 某種屬性的所有字符。比如你可以使用\p{Number}來(lái)匹配所有的Unicode數(shù)字,例如,假設(shè)你想匹配的Unicode字符?字符串:

 
 
 
 
  1. const str = '?'; 
  2. console.log(/\d/u.test(str));    // → false 
  3. console.log(/\p{Number}/u.test(str));     // → true 

同樣的,你可以使用\p{Alphabetic}來(lái)匹配所有的Unicode單詞字符:

 
 
 
 
  1. const str = '?'; 
  2. console.log(/\p{Alphabetic}/u.test(str));     // → true 
  3. // the \w shorthand cannot match ? 
  4. console.log(/\w/u.test(str));    // → false 

同樣有一個(gè)負(fù)向的Unicode屬性轉(zhuǎn)義模板 \P{...}

 
 
 
 
  1. console.log(/\P{Number}/u.test('?'));    // → false 
  2. console.log(/\P{Number}/u.test('?'));    // → true 
  3. console.log(/\P{Alphabetic}/u.test('?'));    // → true 
  4. console.log(/\P{Alphabetic}/u.test('?'));    // → false 

除了字母和數(shù)字之外,Unicode屬性轉(zhuǎn)義中還可以使用其他一些屬性。

以上這幾個(gè)特性的支持情況

ES10新特性

1.Array.prototype.flat()

多維數(shù)組是一種常見(jiàn)的數(shù)據(jù)格式,特別是在進(jìn)行數(shù)據(jù)檢索的時(shí)候。將多維數(shù)組打平是個(gè)常見(jiàn)的需求。通常我們能夠?qū)崿F(xiàn),但是不夠優(yōu)雅。

flat() 方法會(huì)按照一個(gè)可指定的深度遞歸遍歷數(shù)組,并將所有元素與遍歷到的子數(shù)組中的元素合并為一個(gè)新數(shù)組返回。

 
 
 
 
  1. newArray = arr.flat(depth) // depth是指定要提取嵌套數(shù)組的結(jié)構(gòu)深度,默認(rèn)值為 1 

接下來(lái)我們看兩個(gè)例子:

 
 
 
 
  1. const numbers1 = [1, 2, [3, 4, [5, 6]]]
  2. console.log(numbers1.flat())// [1, 2, 3, 4, [5, 6]]
  3. const numbers2 = [1, 2, [3, 4, [5, 6]]]
  4. console.log(numbers2.flat(2))// [1, 2, 3, 4, 5, 6] 

上面兩個(gè)例子說(shuō)明flat 的參數(shù)沒(méi)有設(shè)置,取默認(rèn)值 1,也就是說(shuō)只扁平化第一級(jí);當(dāng) flat 的參數(shù)大于等于 2,返回值就是 [1, 2, 3, 4, 5, 6] 了。

Array.prototype.flat的支持情況:

2.Array.prototype.flatMap()

有了flat方法,那自然而然就有Array.prototype.flatMap方法,flatMap() 方法首先使用映射函數(shù)映射每個(gè)元素,然后將結(jié)果壓縮成一個(gè)新數(shù)組。從方法的名字上也可以看出來(lái)它包含兩部分功能:一個(gè)是 map,一個(gè)是 flat(深度為1)。

 
 
 
 
  1. let arr = [1, 2, 3] 
  2. console.log(arr.map(item => [item * 2]).flat()) // [2, 4, 6] 
  3. console.log(arr.flatMap(item => [item * 2])) // [2, 4, 6] 

實(shí)際上flatMap是綜合了map和flat的操作,所以它也只能打平一層。

Array.prototype.flatmap的支持情況:

3.Object.fromEntries()

Object.fromEntries 這個(gè)新的API實(shí)現(xiàn)了與 Object.entries 相反的操作。這使得根據(jù)對(duì)象的 entries 很容易得到 object。

 
 
 
 
  1. const object = { x: 23, y:24 }; 
  2. const entries = Object.entries(object); //[['x', 23], ['y', 24]]
  3. const result = Object.fromEntries(entries); // { x: 23, y: 24 } 

ES2017引入了Object.entries, 這個(gè)方法可以將對(duì)象轉(zhuǎn)換為數(shù)組,這樣對(duì)象就可以使用數(shù)組原型中的眾多內(nèi)置方法,比如map、 filter、reduce,舉個(gè)例子,我們想提取下列對(duì)象obj中所有value大于21的鍵值對(duì),如何操作呢?

 
 
 
 
  1. // ES10之前 
  2. const obj = { 
  3.   a: 21, 
  4.   b: 22, 
  5.   c: 23 
  6. console.log(Object.entries(obj)) //[['a',21],["b", 22],["c", 23]]
  7. let arr = Object.entries(obj).filter(([a, b]) => b > 21) //[["b", 22],["c", 23]]
  8. let obj1 = {} 
  9. for (let [name, age] of arr) { 
  10.   obj1[name] = age 
  11. console.log(obj1) // {b: 22, c: 23} 

上例中得到了數(shù)組arr,想再次轉(zhuǎn)化為對(duì)象,就需要手動(dòng)寫一些代碼來(lái)處理,但是有了Object.fromEntries()就很容易實(shí)現(xiàn)

 
 
 
 
  1. // 用Object.fromEntries()來(lái)實(shí)現(xiàn) 
  2. const obj = { 
  3.   a: 21, 
  4.   b: 22, 
  5.   c: 23 
  6. let res = Object.fromEntries(Object.entries(obj).filter(([a, b]) => b > 21)) 
  7. console.log(111, res) // {b: 22, c: 23} 

Object.fromEntries()的支持情況:

4.String.trimStart 和 String.trimEnd

移除開(kāi)頭和結(jié)尾的空格,之前我們用正則表達(dá)式來(lái)實(shí)現(xiàn),現(xiàn)在ES10新增了兩個(gè)新特性,讓這變得更簡(jiǎn)單!

trimStart() 方法從字符串的開(kāi)頭刪除空格,trimLeft()是此方法的別名。

 
 
 
 
  1. let str = ' 前端工匠 ' 
  2. console.log(str.length) // 6 
  3. str = str.trimStart() 
  4. console.log(str.length) // 5 
  5. let str1 = str.trim() // 清除前后的空格 
  6. console.log(str1.length) // 4 
  7. str.replace(/^\s+/g, '') // 也可以用正則實(shí)現(xiàn)開(kāi)頭刪除空格 

trimEnd() 方法從一個(gè)字符串的右端移除空白字符,trimRight 是 trimEnd 的別名。

 
 
 
 
  1. let str = ' 浪里行舟 ' 
  2. console.log(str.length) // 6 
  3. str = str.trimEnd() 
  4. console.log(str.length) // 5 
  5. let str1 = str.trim() //清除前后的空格 
  6. console.log(str1.length) // 4 
  7. str.replace(/\s+$/g, '') // 也可以用正則實(shí)現(xiàn)右端移除空白字符 

String.trimStart和String.trimEnd 兩者兼容性一致,下圖以trimStart為例:

5.String.prototype.matchAll

如果一個(gè)正則表達(dá)式在字符串里面有多個(gè)匹配,現(xiàn)在一般使用g修飾符或y修飾符,在循環(huán)里面逐一取出。

 
 
 
 
  1. function collectGroup1 (regExp, str) { 
  2.   const matches = [] 
  3.   while (true) { 
  4.     const match = regExp.exec(str) 
  5.     if (match === null) break 
  6.     matches.push(match[1]) 
  7.   } 
  8.   return matches 
  9. console.log(collectGroup1(/"([^"]*)"/g, `"foo" and "bar" and "baz"`)) 
  10. // [ 'foo', 'bar', 'baz' ] 

值得注意的是,如果沒(méi)有修飾符 /g, .exec() 只返回第一個(gè)匹配?,F(xiàn)在通過(guò)ES9的String.prototype.matchAll方法,可以一次性取出所有匹配。

 
 
 
 
  1. function collectGroup1 (regExp, str) { 
  2.   let results = [] 
  3.   for (const match of str.matchAll(regExp)) { 
  4.     results.push(match[1]) 
  5.   } 
  6.   return results 
  7. console.log(collectGroup1(/"([^"]*)"/g, `"foo" and "bar" and "baz"`)) 
  8. // ["foo", "bar", "baz"] 

上面代碼中,由于string.matchAll(regex)返回的是遍歷器,所以可以用for...of循環(huán)取出。

String.prototype.matchAll的支持情況:

6.try…catch

在ES10中,try-catch語(yǔ)句中的參數(shù)變?yōu)榱艘粋€(gè)可選項(xiàng)。以前我們寫catch語(yǔ)句時(shí),必須傳遞一個(gè)異常參數(shù)。這就意味著,即便我們?cè)赾atch里面根本不需要用到這個(gè)異常參數(shù)也必須將其傳遞進(jìn)去

 
 
 
 
  1. // ES10之前 
  2. try { 
  3.   // tryCode 
  4. } catch (err) { 
  5.   // catchCode 

這里 err 是必須的參數(shù),在 ES10 可以省略這個(gè)參數(shù):

 
 
 
 
  1. // ES10 
  2. try { 
  3.   console.log('Foobar') 
  4. } catch { 
  5.   console.error('Bar') 

try…catch的支持情況:

7.BigInt

JavaScript 所有數(shù)字都保存成 64 位浮點(diǎn)數(shù),這給數(shù)值的表示帶來(lái)了兩大限制。一是數(shù)值的精度只能到 53 個(gè)二進(jìn)制位(相當(dāng)于 16 個(gè)十進(jìn)制位),大于這個(gè)范圍的整數(shù),JavaScript 是無(wú)法精確表示的,這使得 JavaScript 不適合進(jìn)行科學(xué)和金融方面的精確計(jì)算。二是大于或等于2的1024次方的數(shù)值,JavaScript 無(wú)法表示,會(huì)返回Infinity。

 
 
 
 
  1. // 超過(guò) 53 個(gè)二進(jìn)制位的數(shù)值,無(wú)法保持精度 
  2. Math.pow(2, 53) === Math.pow(2, 53) + 1 // true 
  3. // 超過(guò) 2 的 1024 次方的數(shù)值,無(wú)法表示 
  4. Math.pow(2, 1024) // Infinity 

現(xiàn)在ES10引入了一種新的數(shù)據(jù)類型 BigInt(大整數(shù)),來(lái)解決這個(gè)問(wèn)題。BigInt 只用來(lái)表示整數(shù),沒(méi)有位數(shù)的限制,任何位數(shù)的整數(shù)都可以精確表示。

創(chuàng)建 BigInt 類型的值也非常簡(jiǎn)單,只需要在數(shù)字后面加上 n 即可。例如,123 變?yōu)?123n。也可以使用全局方法 BigInt(value) 轉(zhuǎn)化,入?yún)?value 為數(shù)字或數(shù)字字符串。

 
 
 
 
  1. const aNumber = 111; 
  2. const aBigInt = BigInt(aNumber); 
  3. aBigInt === 111n // true 
  4. typeof aBigInt === 'bigint' // true 
  5. typeof 111 // "number" 
  6. typeof 111n // "bigint" 

如果算上 BigInt,JavaScript 中原始類型就從 6 個(gè)變?yōu)榱?7 個(gè)。

  • Boolean

  • Null

  • Undefined

  • Number

  • String

  • Symbol (new in ECMAScript 2015)

  • BigInt (new in ECMAScript 2019)

BigInt的支持情況:

8.Symbol.prototype.description

我們知道,Symbol 的描述只被存儲(chǔ)在內(nèi)部的 [[Description]],沒(méi)有直接對(duì)外暴露,我們只有調(diào)用 Symbol 的 toString() 時(shí)才可以讀取這個(gè)屬性:

 
 
 
 
  1. Symbol('desc').description;  // "desc" 
  2. Symbol('').description;      // "" 
  3. Symbol().description;        // undefined 

Symbol.prototype.description的支持情況:

9.Function.prototype.toString()

ES2019中,F(xiàn)unction.toString()發(fā)生了變化。之前執(zhí)行這個(gè)方法時(shí),得到的字符串是去空白符號(hào)的。而現(xiàn)在,得到的字符串呈現(xiàn)出原本源碼的樣子:

 
 
 
 
  1. function sum(a, b) { 
  2.   return a + b; 
  3. console.log(sum.toString()); 
  4. // function sum(a, b) { 
  5. //  return a + b; 
  6. // } 

Function.prototype.toString()的支持情況:

參考資料

  • 再學(xué)JavaScript ES(6-10)全版本語(yǔ)法大全

  • ECMAScript 6 入門

  • MDN文檔

  • ES2019新特性你知道哪些?

  • ES2018新特性——每個(gè)JS開(kāi)發(fā)者都需要了解

  • 細(xì)解JavaScript ES7 ES8 ES9 新特性

作者簡(jiǎn)介:

浪里行舟:碩士研究生,專注于前端。個(gè)人公眾號(hào):「前端工匠」,致力于打造適合初中級(jí)工程師能夠快速吸收的一系列優(yōu)質(zhì)文章!

【原創(chuàng)稿件,合作站點(diǎn)轉(zhuǎn)載請(qǐng)注明原文作者和出處為.com】


文章名稱:盤點(diǎn)ES7、ES8、ES9、ES10的新特性
分享地址:http://www.5511xx.com/article/cocjidg.html