es2017
- Object.values
- Object.entries()
- Object.getOwnPropertyDescriptors()返回一个对象的所有自身属性的描述符(.value,.writable,.get,.set,.configurable,enumerable)
- padStart()和padEnd()
es2018
- async/await
- Promise.finally
- rest/扩展运算符支持了对象
const object = {
a: 1,
b: 2,
c: 3,
d: 4,
e: 5
};
const { a,b, ...rest } = object;
// a = 1
// b = 2
// rest = { c: 3, d: 4, e: 5 }
es2019
- Object.fromEntries 和 Object.entries相反
- Array.prototype.flat,其接受一个可选参数表示需要展开的深度,默认值为1,可以帮助我们快速实现数组降维
const arr1 = [0, 1, 2, [3, 4]]
console.log(arr1.flat())
// expected output: [0, 1, 2, 3, 4]
const arr2 = [0, 1, 2, [[[3, 4]]]]
console.log(arr2.flat(2))
// expected output: [0, 1, 2, [3, 4]]
flatMap()方法首先使用映射函数映射每个元素,然后将结果压缩成一个新数组。它与 map 连着深度值为 1 的 flat 几乎相同,但 flatMap 通常在合并成一种方法的效率稍微高一些。
const arr1 = [1, 2, [3], [4, 5], 6, []]
const flattened = arr1.flatMap(num => num)
console.log(flattened)
// expected output: Array [1, 2, 3, 4, 5, 6]
- String.trimStart 和 String.trimEnd
- 等价于之前的String.trimRight 和 String.trimLeft
- Function.toString() 更新
- 之前的版本中,Function.toString()直接把空格去掉
- 但是,在ES2019中,会完全保留源码格式打印
es2020
- 可选链操作符(Optional Chaining
let nestedProp = obj?.first?.second
- 如果obj或obj.first是null/undefined,表达式将会短路计算直接返回undefined
- 空位合并操作符(Nullish coalescing Operator
let x = {
profile: {
name: '浪里行舟',
age: ''
}
}
console.log(x.profile.age || 18)
- 上例中age的属性为空字符串,却被等同为假值,为了解决这个问题
let c = a ?? b;
// 等价于let c = a !== undefined && a !== null ? a : b;
- Promise.allSettled
- Promise.allSettled跟Promise.all类似, 其参数接受一个Promise的数组, 返回一个新的Promise, 唯一的不同在于, 它不会进行短路, 也就是说当Promise全部处理完成后,我们可以拿到每个Promise的状态, 而不管是否处理成功
Promise.allSettled([
Promise.reject({ code: 500, msg: '服务异常' }),
Promise.resolve({ code: 200, list: [] }),
Promise.resolve({ code: 200, list: [] })
]).then(res => {
console.log(res)
/*
0: {status: "rejected", reason: {…}}
1: {status: "fulfilled", value: {…}}
2: {status: "fulfilled", value: {…}}
*/
// 过滤掉 rejected 状态,尽可能多的保证页面区域数据渲染
RenderContent(
res.filter(el => {
return el.status !== 'rejected'
})
)
})
- String.prototype.matchAll
const regexp = /t(e)(st(\d?))/g
const str = 'test1test2'
const array = [...str.matchAll(regexp)]
console.log(array[0])
// expected output: Array ["test1", "e", "st1", "1"]
console.log(array[1])
// expected output: Array ["test2", "e", "st2", "2"]
- Dynamic import
el.onclick = () => {
import('/modules/my-module.js')
.then(module => {
})
.catch(err => {
})
}
let module = await import('/modules/my-module.js');
- BigInt
- 它是第7个原始类型,可安全地进行大数整型计算
- 创建 BigInt 类型的值也非常简单,只需要在数字后面加上 n 即可。例如,123 变为 123n
- globalThis
- globalThis 是一个全新的标准方法用来获取全局 this
- 如果您在浏览器上,globalThis将为window,如果您在Node上,globalThis则将为global。因此,不再需要考虑不同的环境问题
// ES2020内置
globalThis.Array(0,1,2) // [0,1,2]
// 定义一个全局对象v = { value:true } ,ES2020用如下方式定义
globalThis.v = { value:true }
es2021
- 数字分割符
1000000000000 1019436871.42
1_000_000_000_000 1_019_436_871.42
- Promise.any
- 接收一个由Promise所组成的可迭代对象,该方法会返回一个新的promise,一旦可迭代对象内的任意一个 promise变成了兑现状态,那么由该方法所返回的 promise就会变成兑现状态,并且它的兑现值就是可迭代对象内的首先兑现的promise的兑现值
- 如果可迭代对象内的promise最终都没有兑现(即所有 promise都被拒绝了),那么该方法所返回的 promise 就会变成拒绝状态
- 并且它的拒因会是一个AggregateError实例,这是Error的子类,用于把单一的错误集合在一起
String.prototype.replaceAll()
'aabbcc'.replaceAll('b', '.')
&&=,仅当左为真时,才将右变量值赋给左变量
let num1 = 5
let num2 = 10
num1 &&= num2
console.log(num1) // 10
||=,仅当左为假时,才将右变量赋给左变量
let num1
let num2 = 10
num1 ||= num2
console.log(num1)
??=,空值合并运算符
let num1
let num2 = 10
num1 ??= num2
console.log(num1)
num1 = false
num1 ??= num2
console.log(num1)
es2022
at()获取索引值
const a = [1,2,3]
a.at(1)
a.at(-1)
- 错误包装
try {
return await fetch('//unintelligible-url-a')
.catch(err => {
throw new Error('Download raw resource failed', { cause: err })
})
} catch (err) {
console.log(err)
console.log('Caused by', err.cause)
}
- 顶层await,顶层 await 能在模块 modules 的顶层正常工作。(在 class 代码块或非 async 函数仍不支持。)
const serviceName = await fetch("https://example.com/what-service-should-i-use")
const service = await import(`/services/${serviceName}.js`)
const params = new URLSearchParams(location.search);
const theme = params.get('theme');
const stylingFunctions = await import(`/styling-functions-${theme}.js`);
const date = new Date()
if(date.getFullYear() === 2023) {
await require('/special-code-for-2023-year.js')
}
- 类的私有属性和方法
class Human {
#name = "John";
setName(name) {
this.#name = name;
}
}
const human = new Human()
human.#name = 'Amy'
human.setName('Amy')
class Human {
name = "John";
constructor(name) {
this.#setName('Amy')
}
#setName(name) {
this.name = name;
}
}
const human = new Human()
human.#setName('Amy')