前言

从 ECMAScript 2016(ES7)开始,版本发布变得更加频繁,每年发布一个新版本,好在每次版本的更新内容并不多,本文会细说这些新特性,尽可能和旧知识相关联,帮你迅速上手这些特性。

一、ES7新特性(2016)

1. Array.prototype.includes()

在ES6中我们有String.prototype.includes(),而在ES7中给Array添加了同样的方法。

2. 指数运算符 **

ES7引入了指数运算符,具有和Math.pow()等效的计算结果。

1
2
console.log(2 ** 10) // 1024
console.log(Math.pow(2, 10)) // 1024

二、ES8新特性(2017)

1. Async/Await

Async是一个通过异步执行并隐式返回Promise作为结果的函数。

2. Object.values() 和 Object.entries()

entries()相当于把对象转换为二维数组。

ES5 引入了Object.keys方法,返回一个数组,成员是参数对象自身的(不含继承的)所有可遍历(enumerable)属性的键名。ES8引入了跟Object.keys配套的Object.values和Object.entries,作为遍历一个对象的补充手段,供for…of循环使用。 它们都用来遍历对象,它会返回一个由给定对象的自身可枚举属性(不含继承的和Symbol属性)组成的数组,数组元素的排列顺序和正常循环遍历该对象时返回的顺序一致。

3. padStart 和 padEnd

用于补齐字符串的长度

1
2
3
4
5
'x'.padStart(4, 'ab') // 'abax'
'x'.padEnd(5, 'ab') // 'xabab'

'12'.padStart(10, 'YYYY-MM-DD') // "YYYY-MM-12"
'09-12'.padStart(10, 'YYYY-MM-DD') // "YYYY-09-12"

4. Object.getOwnPropertyDescriptors()

该方法的引入目的,主要是为了解决Object.assign()无法正确拷贝get属性和set属性的问题。

5. ES8规定函数的参数列表的结尾可以为逗号:

1
function person( name, age, sex, ) {}

主要作用是方便使用git进行多人协作开发时修改同一个函数减少不必要的行变更。

三、ES9新特性(2018)

1. for await…of

该方法称为异步迭代器,主要用来遍历异步对象。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
function Gen (time) {
return new Promise((resolve,reject) => {
setTimeout(function () {
resolve(time)
},time)
})
}

async function test () {
let arr = [Gen(2000),Gen(100),Gen(3000)]
for await (let item of arr) {
console.log(Date.now(),item)
}
}
test()

2. Promise.prototype.finally()

3. 新的正则表达式特性

4. 对象的扩展运算符(ES6只为数组引入了扩展运算符)

1
2
3
4
5
6
7
const obj = {a: 1, b: 2, c: 3};
const {a, ...rest} = obj;
console.log(rest); // 输出 {b: 2, c: 3}

(function({a, ...obj}) {
console.log(obj); // 输出 {b: 2, c: 3}
}({a: 1, b: 2, c: 3}));

5. 对象的Rest

1
2
3
4
const obj = {foo: 1, bar: 2, baz: 3};
const {foo, ...rest} = obj;

console.log(rest); // {bar: 2, baz: 3}

在函数参数中,rest表示所有剩下的参数:

1
2
3
4
5
function func({param1, ...rest}) {
return rest;
}

console.log(func({param1:1, b:2, c:3, d:4})) // {b: 2, c: 3, d: 4}

在对象字面量中,rest运算符只能放在对象的最顶层,并且只能使用一次,要放在最后:

1
2
3
const {...rest, foo} = obj; // Uncaught SyntaxError: Rest element must be last element

const {foo, ...rest1, ...rest2} = obj; // Uncaught SyntaxError: Rest element must be last element

四、ES10新特性(2019)

1. Array.prototype.flat() 多维数组扁平化

1
2
const array = [ 1, [ 2, [ 3, [ 4, [ 5 ] ] ] ] ]
const flatAll = array.flat(Infinity) // [ 1, 2, 3, 4, 5 ]

2. Array.prototype.flatMap()

1
2
3
let arr = [1, 2, 3]
console.log(arr.map(item => [item * 2]).flat()) // [2, 4, 6]
console.log(arr.flatMap(item => [item * 2])) // [2, 4, 6]

flatMap综合了map和flat的操作

3. Object.fromEntries()

Object.fromEntries 这个新的API实现了与Object.entries相反的操作。

1
2
3
const object = { x: 23, y:24 };
const entries = Object.entries(object); // [['x', 23], ['y', 24]] 相当于对象转换数组
const result = Object.fromEntries(entries); // { x: 23, y: 24 } 相当于将数组转换为对象

同时也能将map转换为对象

1
2
3
4
5
const entries = new Map([
['foo', 'bar'],
['baz', 42]
])
Object.fromEntries(entries) // { foo: "bar", baz: 42 }

4. String.trimStart 和 String.trimEnd

在ES10之前,JavaScript提供了trim()方法,用于移除字符串首尾空白符。

现在提供这两个特性,用于移除字符串开头和结尾的空白符(包括空格、制表符tab、换行符等其他空白符等)。之前我们需要用正则表达式来实现,现在ES10新增了两个新特性,让这变得更简单!

1
2
3
const s = '  abc  ';

s.trimStart() // "abc "

trimStart() 和 trimEnd()方法的行为与trim()一致,不过会返回一个从原始字符串开头或结尾删除了空白的新字符串,不会修改原始字符串;

5. catch

在ES10中,try-catch语句中的参数变为了一个可选项。以前我们写catch语句时,必须传递一个异常参数。这就意味着,即便我们在catch里面根本不需要用到这个异常参数也必须将其传递进去

1
2
3
4
5
6
7
8
9
10
11
12
13
14
// ES10之前
try {
// tryCode
} catch (err) {
// catchCode
}

这里 err 是必须的参数,在 ES10 可以省略这个参数:
// ES10
try {
console.log('Foobar')
} catch {
console.error('Bar')
}

6. Symbol.prototype.description

我们知道,Symbol 的描述只被存储在内部的 [[Description]],没有直接对外暴露,我们之前只有调用 Symbol 的 toString() 或使用String()方法来读取这个属性,现在添加了description来直接访问描述:

1
2
3
Symbol('desc').description;  // "desc"
Symbol('').description; // ""
Symbol().description; // undefined

7. Function.prototype.toString()

ES2019中,Function.toString()发生了变化。之前执行这个方法时,得到的字符串是去空白符号的。而现在,得到的字符串呈现出原本源码的样子,会保留注释、空格等。

1
2
3
4
5
6
function sayHi() {
/* dog */
console.log('wangwang');
}

sayHi.toString(); // 将输出和上面一样的原始代码