ECMAScript2019新特性总结及使用场景
1. Object.fromEntries
Object.fromEntries()
方法接收一个键值对的列表参数,并返回一个带有这些键值对的新对象。这个迭代参数应该是一个能够实现@@iterator
方法的的对象,返回一个迭代器对象。它生成一个具有两个元素的类数组的对象,第一个元素是将用作属性键的值,第二个元素是与该属性键关联的值。
Object.fromEntries()
执行与 Object.entries
互逆的操作。
const entries = new Map([
["foo", "bar"],
["baz", 42],
]);
const obj = Object.fromEntries(entries);
console.log(obj);
// Object { foo: "bar", baz: 42 }
1.1 Map 转化为 Object
通过 Object.fromEntries
, 可以将 Map
转换为 Object
:
const map = new Map([
["foo", "bar"],
["baz", 42],
]);
const obj = Object.fromEntries(map);
console.log(obj); // { foo: "bar", baz: 42 }
1.2 Array 转化为 Object
通过 Object.fromEntries
, 可以将 Array
转换为 Object
:
const arr = [
["0", "a"],
["1", "b"],
["2", "c"],
];
const obj = Object.fromEntries(arr);
console.log(obj); // { 0: "a", 1: "b", 2: "c" }
1.3 对象转换
Object.fromEntries
是与 Object.entries()
相反的方法,用 数组处理函数 可以像下面这样转换对象:
const object1 = { a: 1, b: 2, c: 3 };
const object2 = Object.fromEntries(
Object.entries(object1).map(([key, val]) => [key, val * 2])
);
console.log(object2);
// { a: 2, b: 4, c: 6 }
2. trimStart 和 trimEnd
trimStart()
方法从字符串的开头删除空格。trimLeft() 是这个方法的别名。
const greeting = " Hello world! ";
console.log(greeting);
// " Hello world! ";
console.log(greeting.trimStart());
// "Hello world! ";
使用 trimStart()
var str = " foo ";
console.log(str.length); // 8
str = str.trimStart(); // 等同于 str = str.trimLeft();
console.log(str.length); // 5
console.log(str); // "foo "
trimEnd()
方法从一个字符串的末端移除空白字符。trimRight() 是这个方法的别名。
const greeting = " Hello world! ";
console.log(greeting);
// " Hello world! ";
console.log(greeting.trimEnd());
// " Hello world!";
使用 trimEnd()
var str = " foo ";
alert(str.length); // 8
str = str.trimRight(); // 或写成str = str.trimEnd();
console.log(str.length); // 6
console.log(str); // ' foo'
3. Array.prototype.flat 与 flatMap
3.1 flat
flat()
方法会按照一个可指定的深度递归遍历数组,并将所有元素与遍历到的子数组中的元素合并为一个新数组返回。
const arr1 = [0, 1, 2, [3, 4]];
console.log(arr1.flat());
// expected output: [0, 1, 2, 3, 4]
const arr2 = [0, 1, 2, [[[3, 4]]]];
console.log(arr2.flat(2));
// expected output: [0, 1, 2, [3, 4]]
3.1.1 扁平化嵌套数组
var arr1 = [1, 2, [3, 4]];
arr1.flat();
// [1, 2, 3, 4]
var arr2 = [1, 2, [3, 4, [5, 6]]];
arr2.flat();
// [1, 2, 3, 4, [5, 6]]
var arr3 = [1, 2, [3, 4, [5, 6]]];
arr3.flat(2);
// [1, 2, 3, 4, 5, 6]
//使用 Infinity,可展开任意深度的嵌套数组
var arr4 = [1, 2, [3, 4, [5, 6, [7, 8, [9, 10]]]]];
arr4.flat(Infinity);
// [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
3.1.2 扁平化与数组空项
flat()
方法会移除数组中的空项:
var arr4 = [1, 2, , 4, 5];
arr4.flat();
// [1, 2, 4, 5]
3.2 flatMap
flatMap()
方法首先使用映射函数映射每个元素,然后将结果压缩成一个新数组。它与 map 连着深度值为 1 的 flat 几乎相同,但 flatMap
通常在合并成一种方法的效率稍微高一些。
3.2.1 map() 与 flatMap()
var arr1 = [1, 2, 3, 4];
arr1.map((x) => [x * 2]);
// [[2], [4], [6], [8]]
arr1.flatMap((x) => [x * 2]);
// [2, 4, 6, 8]
// only one level is flattened
arr1.flatMap((x) => [[x * 2]]);
// [[2], [4], [6], [8]]
虽然上面的代码使用 map 和 flatMap 好像都可以,但这只能展示如何使用 flatMap。 所以,为了更好的展示 flatMap 的作用,下面我们将包含几句话的数组拆分成单个词组成的新数组。
let arr1 = ["it's Sunny in", "", "California"];
arr1.map((x) => x.split(" "));
// [["it's","Sunny","in"],[""],["California"]]
arr1.flatMap((x) => x.split(" "));
// ["it's","Sunny","in", "", "California"]
注意,输出列表长度可以不同于输入列表长度。
3.2.2 在一个 map() 期间增加或去除一些项
flatMap
能用于在 map 期间增删项目(也就是修改 items 的数量)。换句话说,它允许你遍历很多项使之成为另一些项(靠分别把它们放进去来处理),而不是总是一对一。 从这个意义上讲,它的作用类似于 filter 的对立面。只需返回一个 1 项元素数组以保留该项,返回一个多元素数组以添加项,或返回一个 0 项元素数组以删除该项。
// Let's say we want to remove all the negative numbers and split the odd numbers into an even number and a 1
let 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]));
// [4, 1, 4, 20, 16, 1, 18]
4. Symbol.prototype.description
description
是一个只读属性,它会返回 Symbol
对象的可选描述的字符串
console.log(Symbol("desc").description);
// "desc"
console.log(Symbol.iterator.description);
// "Symbol.iterator"
console.log(Symbol.for("foo").description);
// "foo"
console.log(`${Symbol("foo").description}bar`);
// "foobar"
4.1 实例
Symbol("desc").toString(); // "Symbol(desc)"
Symbol("desc").description; // "desc"
Symbol("").description; // ""
Symbol().description; // undefined
// well-known symbols
Symbol.iterator.toString(); // "Symbol(Symbol.iterator)"
Symbol.iterator.description; // "Symbol.iterator"
// global symbols
Symbol.for("foo").toString(); // "Symbol(foo)"
Symbol.for("foo").description; // "foo"