ES10(ES2019)新特性
发布时间:2019年6月 ES10 新增了数组扁平化、对象转换、字符串修剪等实用方法。
1. Array.prototype.flat()
将嵌套数组"拉平",返回一个新数组:
基本用法
[1, 2, [3, 4]].flat(); // [1, 2, 3, 4]
[1, 2, [3, [4, 5]]].flat(); // [1, 2, 3, [4, 5]],默认只拉平一层
[1, 2, [3, [4, 5]]].flat(2); // [1, 2, 3, 4, 5],拉平两层
使用 Infinity 拉平任意深度
[1, [2, [3, [4, [5]]]]].flat(Infinity); // [1, 2, 3, 4, 5]
实际应用
// 从多层嵌套中提取值
let data = [[1, 2], [3, 4], [5, 6]];
data.flat(); // [1, 2, 3, 4, 5, 6]
// 清除数组空位
[1, , 3, , 5].flat(); // [1, 3, 5]
// 树形数据提取 ID
let tree = [
{ id: 1, children: [{ id: 2 }, { id: 3 }] },
{ id: 4, children: [] }
];
let ids = tree.flatMap(node => [node.id, ...node.children.map(c => c.id)]);
// [1, 2, 3, 4]
注意
- 空位会被自动跳过
- 超过4层嵌套时建议用
Infinity
2. Array.prototype.flatMap()
先执行 map() 再执行 flat(),效率更高:
[1, 2, 3].flatMap(x => [x, x * 2]);
// [1, 2, 2, 4, 3, 6]
// 等同于
[1, 2, 3].map(x => [x, x * 2]).flat();
与 map + flat 的区别
// map + flat:可以指定 flat 深度
[1, [2, [3]]].map(x => x).flat(2); // [1, 2, 3]
// flatMap:只能拉平一层
[1, [2, [3]]].flatMap(x => x); // [1, 2, [3]]
实际应用
// 将句子拆分为单词数组
let sentences = ["Hello World", "Good Morning"];
let words = sentences.flatMap(s => s.split(' '));
// ['Hello', 'World', 'Good', 'Morning']
// 一对多映射
let users = [
{ name: '张三', hobbies: ['篮球', '游泳'] },
{ name: '李四', hobbies: ['足球'] }
];
let hobbies = users.flatMap(u => u.hobbies);
// ['篮球', '游泳', '足球']
// 过滤 + 映射一步完成
[1, 2, 3, 4].flatMap(x => x > 2 ? [x] : []);
// [3, 4]
3. Object.fromEntries()
将键值对列表转为对象,是 Object.entries() 的逆操作:
// entries:对象 → 键值对数组
let entries = Object.entries({ a: 1, b: 2 });
// [['a', 1], ['b', 2]]
// fromEntries:键值对数组 → 对象
let obj = Object.fromEntries(entries);
// { a: 1, b: 2 }
实际应用
过滤对象属性
let obj = { a: 1, b: 2, c: 3, d: 4 };
let filtered = Object.fromEntries(
Object.entries(obj).filter(([k, v]) => v > 2)
);
// { c: 3, d: 4 }
映射对象值
let prices = { apple: 5, banana: 3, orange: 4 };
let doubled = Object.fromEntries(
Object.entries(prices).map(([k, v]) => [k, v * 2])
);
// { apple: 10, banana: 6, orange: 8 }
转换 Map 为对象
let map = new Map([['a', 1], ['b', 2]]);
let obj = Object.fromEntries(map);
// { a: 1, b: 2 }
URL 参数处理
let params = new URLSearchParams('name=张三&age=18');
let obj = Object.fromEntries(params);
// { name: '张三', age: '18' }
4. String.prototype.trimStart()
去除字符串开头的空白字符:
' hello world '.trimStart(); // 'hello world '
' hello world '.trimLeft(); // 'hello world '(别名)
去除的字符
- 空格、制表符
\t、换行符\n、回车符\r等
5. String.prototype.trimEnd()
去除字符串末尾的空白字符:
' hello world '.trimEnd(); // ' hello world'
' hello world '.trimRight(); // ' hello world'(别名)
对比 trim()
' hello '.trim(); // 'hello'(两端都去)
' hello '.trimStart(); // 'hello '(只去开头)
' hello '.trimEnd(); // ' hello'(只去末尾)
6. 可选的 catch 绑定(Optional catch binding)
catch 参数可以省略:
// 旧写法:必须写参数
try {
JSON.parse('invalid');
} catch (err) {
console.log('出错了');
}
// ES10 新写法:可以省略参数
try {
JSON.parse('invalid');
} catch {
console.log('出错了');
}
使用场景
当不需要使用错误对象时:
function parseJSON(str) {
try {
return JSON.parse(str);
} catch {
return null; // 不需要错误信息,返回默认值
}
}
7. Symbol.prototype.description
获取 Symbol 的描述字符串:
let s1 = Symbol('hello');
s1.description; // 'hello'
let s2 = Symbol('');
s2.description; // ''
let s3 = Symbol();
s3.description; // undefined
let s4 = Symbol('你好');
s4.description; // '你好'
对比 toString()
let s = Symbol('test');
s.toString(); // 'Symbol(test)'
s.description; // 'test'(只返回描述,不带 Symbol())
8. JSON superset(JSON 超集)
ES10 允许在 JSON 字符串中使用 U+2028(行分隔符)和 U+2029(段分隔符):
// ES9 及之前,这两个字符在字符串中会导致语法错误
// ES10 修复了这个问题
const json = '"\u2028"';
JSON.parse(json); // ES10 中正常工作
这个改动是内部修复,对日常开发感知不强。
9. Function.prototype.toString() 修订
toString() 返回函数的源代码,包括注释和空格:
function hello() {
/* 注释 */
return 'world';
}
console.log(hello.toString());
// 输出完整的函数源码,包括注释
// "function hello() {\n /* 注释 */\n return 'world';\n}"
10. Array.prototype.sort() 稳定性
ES10 规范要求 Array.sort() 必须是稳定排序:
let items = [
{ name: 'A', order: 1 },
{ name: 'B', order: 1 },
{ name: 'C', order: 2 }
];
// 稳定排序:相同 order 的元素保持原始顺序
items.sort((a, b) => a.order - b.order);
// A 仍在 B 前面(保持原始相对顺序)
总结
| 特性 | 说明 | 重要性 |
|---|---|---|
Array.flat() |
数组扁平化 | ⭐⭐⭐⭐ |
Array.flatMap() |
map + flat 组合 | ⭐⭐⭐⭐ |
Object.fromEntries() |
键值对数组转对象 | ⭐⭐⭐⭐ |
String.trimStart() |
去除开头空白 | ⭐⭐⭐ |
String.trimEnd() |
去除末尾空白 | ⭐⭐⭐ |
| 可选 catch 绑定 | catch 可省略参数 | ⭐⭐⭐ |
Symbol.description |
获取 Symbol 描述 | ⭐⭐ |
| JSON 超集 | 支持行分隔符 | ⭐ |
Function.toString() |
返回完整源码 | ⭐ |
| 稳定排序 | sort 保证稳定性 | ⭐⭐ |
ES6+新特性 文章被收录于专栏
包含ES6+新特性
查看11道真题和解析