這些ES特性你用了嗎?
今天這篇文章的靈感來自于日常的項(xiàng)目開發(fā),「 我以為vue項(xiàng)目中已經(jīng)添加了對可選鏈的支持,但在使用的時(shí)候會(huì)報(bào)錯(cuò),所以我更新了cli,發(fā)現(xiàn)最新版的cli已經(jīng)對babel進(jìn)行了更新 ,也就是對ES的新的一些特性已支持 」。
簡單的歸納了幾個(gè)點(diǎn):
- Array新方法find、findIndex、includes、flat等
 - Object新方法entries、fromEntries、Object.getOwnPropertyDescriptors等
 - String新方法padStart、padStart、trimStart、trimEnd、
 - for await of
 - Function.prototype.toString
 
接下來展開討論一下。
Array
在項(xiàng)目中我們常常會(huì)遇到對數(shù)組的操作是
- 數(shù)組中判斷是否有該字段
 - 在數(shù)組中找到某一對象
 - 多維數(shù)組平鋪
 - 拼接、過濾、排序、裁剪、填充等
 
在ES6中我們判斷一個(gè)字符串中是否包含某一個(gè)字符,我們可以用includes:
- let str = '驚天碼盜';
 - str.includes('驚天');
 - // true
 
而在ES7中也加入了對數(shù)組的支持
- const arr = [1, 3, 5, 2, '8', NaN, -0, undefined]
 - arr.includes(1) // true
 - arr.includes(1, 2) // false 該方法的第二個(gè)參數(shù)表示搜索的起始位置,默認(rèn)為 0
 - arr.includes('1') // false
 - arr.includes(NaN) // true
 - arr.includes(+0) // true
 - arr.includes(undefined) // true
 
在業(yè)務(wù)代碼中遇到最多的就是在數(shù)組中找到某一對象
- const list = [{ id: 1, name: 'Jok' }, { id: 2, name: 'Tom' }]
 - // 判斷l(xiāng)ist是否存在Tom
 - const isHasTome = list.some(e => e.name == "Tom");
 - // true
 - const jokItem = list.find(e => e.name == "Tom");
 - // { id: 2, name: 'Tom' }
 - const jokIndex = list.findIndex(e => e.name == "Tom");
 - // 1
 - // 檢查數(shù)組所有元素是否符合指定條件
 - const hasPropToName = list.every(e => e.name)
 - // true 檢查每一項(xiàng)是否有name屬性
 
在ES10中新增了一個(gè)flat方法,將多維數(shù)組打平:
- const arr = [1, 2, [3, [4, 5], 6], 7]
 - arr.flat();
 - // [1, 2, 3, [4, 5], 6, 7]
 - arr.flat(2);
 - // [1, 2, 3, 4, 5, 6, 7]
 - //arr.flat(depth)
 - // depth 是指定要提取嵌套數(shù)組的結(jié)構(gòu)深度,默認(rèn)值為 1
 
在ES6中還有一個(gè)比較有意思的API,就是entries
- // 數(shù)組迭代器
 - const iterator = list.entries()
 - iterator.next();
 - // { done: false, value:[ 0, { id: 1, name: 'Jok' }] }
 - iterator.next();
 - // { done: false, value:[ 1, { id: 2, name: 'Tom' }] }
 - iterator.next();
 - // { done: true, value: undefined}
 
有點(diǎn)類似generator函數(shù)。
- // 處理promise
 - const promiseCase = (p) => {
 - return new Promise(function (resolve, reject) {
 - setTimeout(function () {
 - resolve(`${p}成功`); //代碼正常執(zhí)行!
 - }, 250);
 - });
 - }
 - const asyncList = [promiseCase('p1'), promiseCase('p2'), promiseCase('p3')];
 - const iterator = asyncList.entries();
 - // undefined
 - for (let e of iterator) {
 - console.log(e);
 - e[1].then(
 - res=>console.log(res)
 - )
 - }
 - // [0, Promise]
 - // [1, Promise]
 - // [2, Promise]
 - // p1成功
 - // p2成功
 - // p3成功
 
Object
ES5引入了Object.keys返回健名。緊跟著ES8引入了Object.values和Object.entries,作為遍歷一個(gè)對象的手段,供for of使用。
- const obj = { foo: 'bar', baz: 42 };
 - Object.keys(obj)
 - // ["foo", "baz"]
 - Object.values(obj)
 - // ["bar", 42]
 - const objEntries = Object.entries(obj)
 - // [["foo", "bar"], ["baz", 42]]
 - Object.fromEntries(objEntries)
 - // {foo: "bar", baz: 42}
 
也可以用entries來判斷對象中某些值的對比:
- const obj = {
 - a: 21,
 - b: 22,
 - c: 23
 - }
 - let res = Object.fromEntries(Object.entries(obj).filter(([a, b]) => b > 21))
 - console.log(res)
 - // {b: 22, c: 23}
 
ES5 的 Object.getOwnPropertyDescriptor() 方法會(huì)返回某個(gè)對象屬性的描述對象(descriptor)。ES8 引入了 Object.getOwnPropertyDescriptors() 方法,返回指定對象所有自身屬性(非繼承屬性)的描述對象。
Object.assign無法正確拷貝get屬性和set屬性,Object.getOwnPropertyDescriptors() 方法配合 Object.defineProperties() 方法,就可以實(shí)現(xiàn)正確拷貝。
- const source = {
 - set foo (value) {
 - console.log(value)
 - },
 - get bar () {
 - return '浪里行舟'
 - }
 - }
 - const target1 = {}
 - Object.assign(target1, source)
 - console.log(Object.getOwnPropertyDescriptor(target1, 'foo'))
 - // undefined
 - const target2 = {}
 - Object.defineProperties(target2, Object.getOwnPropertyDescriptors(source))
 - console.log(Object.getOwnPropertyDescriptor(target2, 'foo'))
 - // set: ƒ foo(value)
 
String
在 ES8 中 String 新增了兩個(gè)實(shí)例函數(shù) String.prototype.padStart 和 String.prototype.padEnd,允許將空字符串或其他字符串添加到原始字符串的開頭或結(jié)尾。
- String.padStart(targetLength,[padString])
 - // targetLength(必填): 當(dāng)前字符串需要填充到的目標(biāo)長度。如果這個(gè)數(shù)值小于當(dāng)前字符串的長度,則返回當(dāng)前字符串本身。
 - // padString(可選): 填充字符串。如果字符串太長,使填充后的字符串長度超過了目標(biāo)長度,則只保留最左側(cè)的部分,其他部分會(huì)被截?cái)啵藚?shù)的缺省值為 " "。
 - 'x'.padStart(4, 'ab') // 'abax'
 - 'x'.padEnd(5, 'ab') // 'xabab'
 
在ES10中新增了兩個(gè)移除開頭和結(jié)尾的空格。
- let str = ' 驚天 碼盜 '
 - str.trimStart(); // str.trimLeft();
 - // '驚天 碼盜 '
 - str.trimEnd(); // str.trimRight();
 - // ' 驚天 碼盜'
 - str.trim();
 - // '驚天 碼盜'
 - str.replace(/\s+/g, '') ;
 - // '驚天碼盜'
 
for await of
for of方法能夠遍歷具有 Symbol.iterator 接口的同步迭代器數(shù)據(jù),但是不能遍歷異步迭代器。ES9 新增的 for await of 可以用來遍歷具有 Symbol.asyncIterator 方法的數(shù)據(jù)結(jié)構(gòu),也就是異步迭代器,且會(huì)等待前一個(gè)成員的狀態(tài)改變后才會(huì)遍歷到下一個(gè)成員,相當(dāng)于 async 函數(shù)內(nèi)部的 await。
我想大家基本都寫過類似這樣的代碼:
- const promiseCase = (p) => {
 - return new Promise(function (resolve, reject) {
 - setTimeout(function () {
 - resolve({
 - code: 0,
 - name: `${p}`
 - }); //代碼正常執(zhí)行!
 - }, 250);
 - });
 - }
 - const asyncList = [promiseCase('p1'), promiseCase('p2'), promiseCase('p3')];
 - asyncList.forEach(async (e) => {
 - const data = await e;
 - console.log(data)
 - })
 - // {code: 0, name: "p1"}
 - // {code: 0, name: "p2"}
 - // {code: 0, name: "p3"}
 
現(xiàn)在可以這樣寫:
- async function test () {
 - for await (let item of asyncList) {
 - console.log(Date.now(), item)
 - }
 - }
 - test()
 - // 1614935341100 {code: 0, name: "p1"}
 - // 1614935341100 {code: 0, name: "p2"}
 - // 1614935341100 {code: 0, name: "p3"}
 
Function.prototype.toString
ES2019 中,F(xiàn)unction.toString() 發(fā)生了變化。之前執(zhí)行這個(gè)方法時(shí),得到的字符串是去空白符號(hào)的。
而現(xiàn)在,得到的字符串呈現(xiàn)出原本源碼的樣子:
- function sum(a, b) {
 - return a + b;
 - }
 - console.log(sum.toString());
 - // function sum(a, b) {
 - // return a + b;
 - // }
 
本文轉(zhuǎn)載自微信公眾號(hào)「驚天碼盜」,可以通過以下二維碼關(guān)注。轉(zhuǎn)載本文請聯(lián)系驚天碼盜公眾號(hào)。
















 
 
 






 
 
 
 