ES10
ECMAScript 10(简称ES10)是于2019年6月正式发布的JavaScript语言的标准,正式名为ECMAScript 2019(ES2019)。
# Array.prototype.{flat,flatMap}
# flat()
该方法会按照一个可指定的深度递归遍历数组,并将所有元素与遍历到的子数组中的元素合并为一个新数组返回。
语法:
var newArray = arr.flat([depth])
参数:
- depth:指定要提取嵌套数组的结构深度,默认值为 1。
返回值:一个包含将数组与子数组中所有元素的新数组。
示例:
let arr = [1, 2, 3, [4, 5, 6, [7, 8, 9, [10, 11, 12]]]];
console.log(arr.flat()) // [ 1, 2, 3, 4, 5, 6, [ 7, 8, 9, [ 10, 11, 12 ] ] ]
console.log(arr.flat().flat()); // [ 1, 2, 3, 4, 5, 6, 7, 8, 9, [ 10, 11, 12 ] ]
console.log(arr.flat(3)); // [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
console.log(arr.flat(Infinity)); // [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
// 移除数组中的空项:
var arr4 = [1, 2, , 4, 5];
arr4.flat(); // [1, 2, 4, 5]
2
3
4
5
6
7
8
9
10
11
12
13
# flatMap()
该方法首先使用映射函数映射每个元素,然后将结果压缩成一个新数组。flatMap 通常在合并成一种方法的效率稍微高一些。
语法:
var new_array = arr.flatMap(function callback(currentValue[, index[, array]]) {
// return element for new_array
}[, thisArg])
2
3
参数:
- callback:可以生成一个新数组中的元素的函数,可以传入三个参数:
- currentValue:当前正在数组中处理的元素
- index:可选的。数组中正在处理的当前元素的索引。
- array:可选的。被调用的 map 数组
- thisArg:可选的。执行 callback 函数时 使用的this 值。
返回值: 一个新的数组,其中每个元素都是回调函数的结果,并且结构深度 depth 值为1。
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]]
2
3
4
5
6
7
8
9
10
11
# String.prototype.{trimStart,trimEnd}
# trimStart()
方法从字符串的开头删除空格。trimLeft() 是此方法的别名。
语法:
str.trimStart();
str.trimLeft();
2
返回值:一个新字符串,表示从其开头(左端)除去空格的调用字符串。
相关信息
- trimStart() / trimLeft() 方法移除原字符串左端的连续空白符并返回一个新字符串,并不会直接修改原字符串本身。
- 为了与 String.prototype.padStart 等函数保持一致,标准方法名称为trimStart。 但是,出于 Web 兼容性原因,trimLeft 仍然是 trimStart 的别名。
var str = " foo ";
console.log(str.length); // 8
str = str.trimStart() // 等同于 str = str.trimLeft();
console.log(str.length); // 5
console.log(str); // "foo "
2
3
4
5
6
7
# trimEnd()
该方法从一个字符串的末端移除空白字符。trimRight() 是这个方法的别名。
语法:
str.trimEnd();
str.trimRight();
2
返回值:一个新字符串,表示从调用字串的末(右)端除去空白。
相关信息
- trimEnd() / trimRight()方法移除原字符串右端的连续空白符并返回,trimEnd() / trimRight()方法并不会直接修改原字符串本身。
- 为了与 String.prototype.padEnd 等函数保持一致,标准方法名称为trimEnd。 但是,出于Web兼容性原因,trimRight仍然是trimEnd的别名。
var str = " foo ";
alert(str.length); // 8
str = str.trimRight(); // 或写成str = str.trimEnd();
console.log(str.length); // 6
console.log(str); // ' foo'
2
3
4
5
6
7
# Well-formed JSON.stringify
之前的 JavaScript 版本中,由于不恰当的范围处理,JSON.stringify() 可能返回非法的 Unicode 转义序列(不在unicode范围内的),Well-formed JSON.stringify 提案修正了这一行为。
// 如果输入超出Unicode范围的字符格式,在原先JSON.stringif中会返回格式错误的Unicode字符串:
JSON.stringify('\uD800');
// → '"�"'
// 现在实现了一个改变JSON.stringify的第3阶段提案,因此它为其输出转义序列,使其成为有效Unicode(并以UTF-8表示):
JSON.stringify('\uD800');
// → '"\ud800"'
2
3
4
5
6
7
# Object.fromEntries
该方法把键值对列表转换为一个对象。
语法:
Object.fromEntries(iterable);
参数:
- iterable:类似 Array 、 Map 或者其它实现了可迭代协议的可迭代对象。
返回值:一个由该迭代对象条目提供对应属性的新对象。
相关信息
Object.fromEntries() 执行与 Object.entries 互逆的操作。
示例:
// Map 转化为 Object
const map = new Map([ ['foo', 'bar'], ['baz', 42] ]);
const obj = Object.fromEntries(map);
console.log(obj); // { foo: "bar", baz: 42 }
// Array 转化为 Object
const arr = [ ['0', 'a'], ['1', 'b'], ['2', 'c'] ];
const obj = Object.fromEntries(arr);
console.log(obj); // { 0: "a", 1: "b", 2: "c" }
// 对象转换
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
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# Function.prototype.toString revision
JavaScript 中,可以通过 Function.prototype.toString() 方法获取函数的原始文本内容,不过,之前的结果并不是真正的原始内容,例如:
// 其中,部分注释内容被剔除并且转义序列被求值。
(function /**/ \u0061 /**/ ( /**/ ) { /**/ }).toString()
// "function a( /**/ ){ /**/ }"
2
3
在 Function.prototype.toString() revision 提案中,将 toString() 的结果调整为真正的原始文本内容,即:
(function /**/ \u0061 /**/ ( /**/ ) { /**/ }).toString()
// "function /**/ \u0061 /**/ ( /**/ ) { /**/ }"
2
相关信息
- 如果Function可以通过以ECMAScript源代码的方式表示的话,则toString会直接返回这个函数的代码。
- 如果是一些native的方法,比如底层c或者c++实现的代码,则直接返回[native code]
Math.pow.toString() 'function pow() { [native code] }'
1
2
# Symbol.prototype.description
description 是一个只读属性,它会返回 Symbol 对象的可选描述的字符串。
语法:
Symbol('myDescription').description;
Symbol.iterator.description;
Symbol.for('foo').description;
2
3
相关信息
Symbol 对象可以通过一个可选的描述创建,可用于调试,但不能用于访问 symbol 本身。Symbol.prototype.description 属性可以用于读取该描述。与 Symbol.prototype.toString() 不同的是它不会包含 "Symbol()" 的字符串。
示例:
// 在ES10之前,我们想要访问Symbol的description是这样做的:
const sym = Symbol('www.flydean.com');
console.log(String(sym)); // //Symbol(www.flydean.com)
// 现在我们可以直接通过description属性来访问了:
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"
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# JSON superset(JSON 被归为ECMAScript的子集)
由于在一些特殊字符处理上的差异,一直以来 JSON 并不是 JavaScript(表达式)的子集,从而在概念上造成了不必要的困扰。 JSON superset 语言提案调整了 JavaScript 中的相关语义,从而保证了合法的 JSON 格式能够直接被用作 JavaScript 表达式使用。
什么是 JSON 超集?简而言之就是让 ECMAScript 兼容所有JSON支持的文本。但由于 JSON 内容可以正常包含 U+2028行分隔符 与 U+2029段分隔符,而ECMAScript 却不行。 JSON.stringify在 ES10 修复了对于一些超出范围的 Unicode展示错误的问题。因为 JSON 都是被编码成 UTF-8,所以遇到 0xD800–0xDFFF 之内的字符会因为无法编码成 UTF-8 进而导致显示错误。在 ES10 它会用转义字符的方式来处理这部分字符而非编码的方式,这样就会正常显示了。
// \uD83D\uDE0E emoji 多字节的一个字符
console.log(JSON.stringify('\uD83D\uDE0E')) // "?"
// 如果我们只去其中的一部分 \uD83D 这其实是个无效的字符串
// 之前的版本 ,这些字符将替换为特殊字符,而现在将未配对的代理代码点表示为JSON转义序列
console.log(JSON.stringify('\uD83D')) // "\ud83d"
2
3
4
5
# Optional catch binding
提案去除了 catch 中必须声明错误对象的强制要求,简化了 try-catch 的使用成本。
在传统的写法中,catch是要接受一个error参数的,但有时候我们已经知道这个异常是不重要的,或者说,我们想忽略掉这个异常。
try {
// ···
} catch (error) {
// ···
}
try {
// ···
} catch {
// ···
}
2
3
4
5
6
7
8
9
10
11