ECMAScript 攻略
Array#{flat,flatMap}
ECMAScript 2019 在 Array.prototype 上增加了两个方法:flat()和 flatMap()。
这两个方法为打平数组提供了便利。如果没有这两个方法,则打平数组就要使用迭代或递归
// 手写实现/*数组中每个元素都像一个子节点,非数组元素是叶节点。因此,这个例子中的输入数组是一个高度为 2 有 7 个叶节点的树。打平这个数组本质上是对叶节点的按序遍历。
第一个参数:源数组第二个参数:指定打平到第几级嵌套第三个参数:新数组
*/
function flatten(sourceArray, depth, flattenedArray = []) { for (const element of sourceArray) { if (Array.isArray(element) && depth > 0) { flatten(element, depth - 1, flattenedArray); } else { flattenedArray.push(element); } } return flattenedArray;}
const arr = [[0], 1, 2, [3, [4, 5]], 6];
console.log(flatten(arr, 1));
// [0, 1, 2, 3, [4, 5], 6]数组的成员有时还是数组,Array.prototype.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]]flatMap()只能展开一层数组。
// 相当于 [[[2]], [[4]], [[6]], [[8]]].flat()[1, 2, 3, 4].flatMap((x) => [[x * 2]]);// [[2], [4], [6], [8]]典型场景: 将包含几句话的数组拆分成单个词组成的新数组
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"]详细内容参考 ES 入门 - flat
Object.fromEntries
提出背景: 前端使用 Map 结构存储数据,但是调用后端 API 时需要传递普通对象,这时候就可以使用Object.fromEntries()进行转换
Object.fromEntries 是与 Object.entries() 相反的方法,用于将一个键值对数组转为对象。
Object.fromEntries([ ["foo", "bar"], ["baz", 42],]);// { foo: "bar", baz: 42 }该方法的主要目的,是将键值对的数据结构还原为对象,因此特别适合将 Map 结构转为对象。
使用场景:
Map 键值对结构转换为对象
// 例一const entries = new Map([ ["foo", "bar"], ["baz", 42],]);
Object.fromEntries(entries);// { foo: "bar", baz: 42 }
// 例二const map = new Map().set("foo", true).set("bar", false);Object.fromEntries(map);// { foo: true, bar: false }Array 转化为 Object
const arr = [ ["0", "a"], ["1", "b"], ["2", "c"],];const obj = Object.fromEntries(arr);console.log(obj); // { 0: "a", 1: "b", 2: "c" }浏览器查询参数转换为对象
let query = Object.fromEntries(new URLSearchParams("foo=bar&baz=qux"));// {foo: "bar", baz: "qux"}console.log(query);将对象的值重新组合
let arr = [ { name: "Alice", age: 40 }, { name: "Bob", age: 36 },];let obj = Object.fromEntries(arr.map(({ name, age }) => [name, age]));// {Alice: 40, Bob: 36}console.log(obj);String#{trimStart,trimEnd}
ES2019 对字符串实例新增了trimStart()和trimEnd()这两个方法。它们的行为与trim()一致,
trimStart()消除字符串头部的空格,trimEnd()消除尾部的空格。
它们返回的都是新字符串,不会修改原始字符串。
const s = " abc ";
s.trim(); // "abc"s.trimStart(); // "abc "s.trimEnd(); // " abc"复制代码Symbol#description
创建 Symbol 的时候,可以添加一个描述。
const sym = Symbol("foo");上面代码中,sym 的描述就是字符串 foo。
但是,读取这个描述需要将 Symbol 显式转为字符串,即下面的写法。
const sym = Symbol("foo");
String(sym); // "Symbol(foo)"sym.toString(); // "Symbol(foo)"上面的用法不是很方便。ES2019 提供了一个实例属性 description,直接返回 Symbol 的描述。
const sym = Symbol("foo");
sym.description; // "foo"ES2019 提供了一个实例属性description,直接返回 Symbol 的描述。
// 创建 Symbol 的时候,可以添加一个描述。const sym = Symbol("foo");
sym.description; // "foo"上面代码中,sym 的描述就是字符串 foo。
try {} catch {} // optional binding
旧版本的try / catch语句中的catch子句需要一个变量。 现在可以不加了
// 旧版本try { console.log(a);} catch (error) { console.log("报错了");}
// ES2019-SE10
// 如果我们对错误信息漠不关心,只想知道是否报错,就可以忽略catch的参数try { console.log(a); return true;} catch { console.log("报错了"); return false;}U+2028 和 U+2029
在 ES2019 之前的版本中,不接受不转义的
- 行分隔符
U + 2028 - 段落分隔符
U + 2029
ES2019 允许 JavaScript 字符串直接输入 U+2028(行分隔符)和 U+2029(段分隔符)。
/*ES2019之前,下面的代码会报错
ES2019 下面代码不会报错。*/const PS = eval("'\u2029'");JSON-stringify - 的改造
为了确保返回的是合法的 UTF-8 字符,ES2019 改变了 JSON.stringify()的行为。如果遇到 0xD800 到 0xDFFF 之间的单个码点,或者不存在的配对形式,它会返回转义字符串,留给应用自己决定下一步的处理。
JSON.stringify("\u{D834}"); // ""\\uD834""JSON.stringify("\uDF06\uD834"); // ""\\udf06\\ud834""Array.prototype.sort() 的稳定排序
早先的 ECMAScript 没有规定,Array.prototype.sort()的默认排序算法是否稳定,留给浏览器自己决定,这导致某些实现是不稳定的。ES2019 明确规定,Array.prototype.sort()的默认排序算法必须稳定。这个规定已经做到了,现在 JavaScript 各个主要实现的默认排序算法都是稳定的。
const arr = ["peach", "straw", "apple", "spork"];
const stableSorting = (s1, s2) => { if (s1[0] < s2[0]) return -1; return 1;};
arr.sort(stableSorting);// ["apple", "peach", "straw", "spork"]revised Function#toString
ES2019 对函数实例的 toString()方法做出了修改。
toString()方法返回函数代码本身,以前会省略注释和空格。
function /* foo comment */ foo() {}
// 老版本foo.toString();// function foo() {}
// 新版foo.toString();// "function /* foo comment */ foo () {}"