每年都有一些新的属性进入标准,今年发布的ECMAScript2019/ES10同样也有很多新的特性,本文将会挑选一些普通开发者会用到的新属性进行深入的解读。
Array.prototype.flat()
The flat() method creates a new array with all sub-array elements concatenated into it recursively up to the specified depth. --
简单来说flat这个函数就是按照一定的深度depth将一个深层次嵌套的数组拍扁, 例子:
const nestedArr = [1, 2, [3, 4, [5, 6, [7, [8], 9]]], 10] console.log(nestedArr.flat()) // [1, 2, 3, 4, [5, 6, [7, [8], 9]], 10] console.log(nestedArr.flat(2)) // [1, 2, 3, 4, 5, 6, [7, [8], 9], 10] console.log(nestedArr.flat(3)) // [1, 2, 3, 4, 5, 6, 7, [8], 9, 10] console.log(nestedArr.flat(4)) // [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] console.log(nestedArr.flat(Infinity)) // [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
由上面的例子可以看出flat会按照指定的深度depth将一个数组扁平化,如果需要将数组完全拍扁变成一维数组,则指定depth为无限大,即是Infinity,相反如果不指定深度,其默认值是1。
Array.prototype.flatMap()
The flatMap() method first maps each element using a mapping function, then flattens the result into a new array. It is identical to a map() followed by a flat() of depth 1, but flatMap() is often quite useful, as merging both into one method is slightly more efficient. --
简单来说flatMap等于一个数组先调用完map函数再调用flat函数将其扁平化,扁平化的深度固定为1,先通过一个简单的例子感受一下:
const myArr = [1, 2, 3] myArr .map(n => [n * n]) // [[1], [4], [9]] .flat() // [1, 4, 9] // 用flatMap可以一步到位 myArr.flatMap(n => [n * n]) // [1, 4, 9]
从上面的例子来看flatMap如果只是将flat和map做了一个简单的组合好像可有可无,其实不然,flatMap有个强大的功能是可以在map的时候添加和删除元素,这个无论是map还是filter都没有这个功能。
要想删除某一个元素只需要在mapper函数里面返回一个空的数组[], 而增加元素只需在mapper函数里面返回一个长度大于1的数组,具体可以看下面的例子:
// 假如我们想要删除掉原数组里面所有的负数,同时将单数转换为一个复数和1 const a = [5, 4, -3, 20, 17, -33, -4, 18] // |\ \ x | | \ x x | // [4,1, 4, 20, 16,1, 18] a.flatMap(n => (n < 0) ? []: // 删除负数 (n % 2 == 0) ? [n] : // 保留复数 [n - 1, 1] // 单数变为一个复数和1 ) // [4, 1, 4, 20, 20, 16, 1, 18]
Object.fromEntries()
The Object.fromEntries() method transforms a list of key-value pairs into an object. --
fromEntries方法将一个对象返回的一系列键值对(key-value pairs)转换为一个object。先看一个简单的例子理解一下:
// key-value pairs数组 const entriesArr = [['k1', 1], ['k2', 2]] console.log(Object.fromEntries(entriesArr) // {k1: 1, k2: 2} const entriesMap = new Map([ ['k1', 1], ['k2', 2] ]) // {"k1" => 1, "k2" => 2} console.log(Object.fromEntries(entriesMap)) // {k1: 1, k2: 2}
再来看一个自定义的iterable对象例子深入理解一下:
const iteratorObj = { [Symbol.iterator]: function () { const entries = [['k1', 1], ['k2', 2]] let cursor = 0 return { next() { const done = entries.length === cursor return { value: done ? undefined : entries[cursor++], done } } } } } Object.fromEntries(iteratorObj) // {k1: 1, k2: 2}
这个方法有一个用途就是对object的key进行filter,举个例子:
const studentMap = { student1: {grade: 80}, student2: {grade: 50}, student3: {grade: 100} } const goodStudentMap = Object.fromEntries( Object .entries(studentMap) .filter(([_, meta]) => meta.grade >= 60) ) console.log(goodStudentMap) // {student1: {grade: 80}, student3: {grade: 100}}
String.prototype.trimStart
这个方法很简单,就是返回一个将原字符串开头的空格字符去掉的新的字符串,例子:
const greeting = ' Hello world! ' console.log(greeting.trimStart()) // 'Hello world! '
这个方法还有一个别名函数,叫做trimLeft,它们具有一样的功能。
String.prototype.trimEnd
这个方法和trimStart类似,只不过是将原字符串结尾的空格字符去掉,例子:
const greeting = ' Hello world! ' console.log(greeting.trimEnd()) // ' Hello world!'
这个方法也有一个别名函数,叫做trimRight, 它们也具有一样的功能。
Symbol.prototype.description
The read-only description property is a string returning the optional description of Symbol objects. --
ECMAScript2019给Symbol对象添加了一个可选的description属性,这个属性是个只读属性,看看例子: