ES2016 ~ ES2019 新特性
约 692 字大约 2 分钟
布欧-Lewyon
2026-05-16
首页 › JavaScript › ES6+ 深入 › ES2016 ~ ES2019 新特性
ES2016 (ES7)
Array.prototype.includes
const arr = [1, 2, 3, NaN];
arr.includes(2); // true
arr.includes(4); // false
arr.includes(NaN); // true(区别于 indexOf)
arr.indexOf(NaN); // -1(indexOf 不能检测 NaN)指数运算符 **
2 ** 3; // 8(2 的 3 次方)
2 ** 0.5; // 1.414...(平方根)
2 ** 10; // 1024
// 从右到左结合
2 ** 3 ** 2; // 512(等于 2 ** 9)ES2017 (ES8)
async/await
Object.values / Object.entries
const obj = { a: 1, b: 2, c: 3 };
Object.values(obj); // [1, 2, 3]
Object.entries(obj); // [['a', 1], ['b', 2], ['c', 3]]String padding
'5'.padStart(3, '0'); // "005"
'5'.padEnd(3, '0'); // "500"
// 对齐输出
console.log('名称'.padEnd(10) + '价格');
console.log('苹果'.padEnd(10) + '5.00');Object.getOwnPropertyDescriptors
const obj = { name: '张三' };
Object.defineProperty(obj, 'age', {
value: 28,
writable: false
});
const descriptors = Object.getOwnPropertyDescriptors(obj);
// { name: { value: '张三', writable: true, ... },
// age: { value: 28, writable: false, ... } }
// 完整浅拷贝(保留属性描述符)
const clone = Object.defineProperties({}, Object.getOwnPropertyDescriptors(obj));尾逗号
// 函数参数、调用参数末尾允许逗号
function sum(a, b,) { }
sum(1, 2,);ES2018 (ES9)
对象的 Rest / Spread
const obj = { a: 1, b: 2, c: 3, d: 4 };
const { a, b, ...rest } = obj;
console.log(rest); // { c: 3, d: 4 }
// 合并对象(后覆盖前)
const merged = { ...obj, e: 5 };Promise.finally
fetch('/api/data')
.then(data => render(data))
.catch(err => handleError(err))
.finally(() => hideLoading()); // 无论成功失败都执行异步迭代器
async function* asyncGenerator() {
yield await Promise.resolve(1);
yield await Promise.resolve(2);
yield await Promise.resolve(3);
}
// for await...of
for await (const value of asyncGenerator()) {
console.log(value); // 1, 2, 3
}RegExp 增强
// 命名捕获组 (?<name>)
const re = /(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})/;
const match = re.exec('2026-05-16');
console.log(match.groups.year); // "2026"
console.log(match.groups.month); // "05"
// 后行断言 (?<=...) / (?<!...)
/(?<=\$)\d+/.test('$100'); // true(美元符号后跟数字)
/(?<!\$)\d+/.test('€100'); // true(非美元符号后跟数字)
// s 标志(dotAll,. 匹配换行)
/foo.bar/s.test('foo\nbar'); // trueES2019 (ES10)
Array.flat / flatMap
[1, [2, [3]]].flat(1); // [1, 2, [3]]
[1, [2, [3]]].flat(2); // [1, 2, 3]
[1, [2, [3]]].flat(Infinity); // [1, 2, 3] 无限展平
['Hello', 'World'].flatMap(s => s.split(''));
// ['H', 'e', 'l', 'l', 'o', 'W', 'o', 'r', 'l', 'd']Object.fromEntries
const entries = [['name', '张三'], ['age', 28]];
const obj = Object.fromEntries(entries);
// { name: '张三', age: 28 }
// 实用:Map 转对象
const map = new Map([['a', 1], ['b', 2]]);
Object.fromEntries(map); // { a: 1, b: 2 }
// 实用:过滤对象键值
const product = { name: '苹果', price: 5, discount: 0 };
const filtered = Object.fromEntries(
Object.entries(product).filter(([_, v]) => v !== 0)
);
// { name: '苹果', price: 5 }String.trimStart / trimEnd
' hello '.trimStart(); // "hello "
' hello '.trimEnd(); // " hello"Symbol.description
const sym = Symbol('用户ID');
console.log(sym.description); // "用户ID"catch 可选绑定
try {
JSON.parse('invalid');
} catch { // 不需要 error 参数(ES2019 起可省略)
console.log('解析失败');
}小结
| 版本 | 主要新特性 |
|---|---|
| ES2016 | includes、** 指数运算符 |
| ES2017 | async/await、Object.values/entries、padStart/End |
| ES2018 | 对象 rest/spread、finally、异步迭代器、正则增强 |
| ES2019 | flat/flatMap、Object.fromEntries、trimStart/End |
上一节:类与继承 下一节:ES2020 ~ ES2024 新特性
