## ES2016 (ES7)
### Array.prototype.includes
```javascript
[1, 2, 3].includes(2); // true
[NaN].includes(NaN); // true(indexOf 不能检测 NaN)
```
### 指数运算符
```javascript
2 ** 10; // 1024
let a = 2; a **= 4; // 16
```
## ES2017 (ES8)
### async/await
```javascript
async function fetchData() {
const response = await fetch('/api/data');
return response.json();
}
```
### Object.values / Object.entries
```javascript
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
```javascript
'5'.padStart(3, '0'); // '005'
'5'.padEnd(3, '0'); // '500'
```
## ES2018 (ES9)
### 对象展开
```javascript
const obj1 = {a: 1, b: 2};
const obj2 = {...obj1, c: 3}; // {a: 1, b: 2, c: 3}
```
### Promise.finally
```javascript
fetch('/api/data')
.then(data => console.log(data))
.catch(err => console.error(err))
.finally(() => console.log('请求完成'));
```
### 正则新特性
```javascript
const re = /(?
const match = re.exec('2024-01');
console.log(match.groups.year); // 2024
```
## ES2019 (ES10)
### Array.flat / flatMap
```javascript
[1, [2, [3]]].flat(2); // [1, 2, 3]
[1, 2, 3].flatMap(x => [x, x * 2]); // [1, 2, 4, 3, 6]
```
### Object.fromEntries
```javascript
Object.fromEntries([['a', 1], ['b', 2]]); // {a: 1, b: 2}
```
### 可选的 catch
```javascript
try { JSON.parse(invalid); }
catch { /* 不需 error 参数 */ }
```