ES2020新特性

近年来JavaScript 一直在快速发展,每次迭代中都会出现大量新功能。ES2020版本的提议已经敲定,都是比较使用的功能,一起来学习一下吧。

可选链

原来我们在访问对象的深层嵌套属性时,需要检查每个级别中定义的属性,保证代码不会因语法错误导致异常,代码如下

1
2
3
4
5
6
7
let props = {
query: {
id: 1
}
}
let id = props && props.query && props.query.id // id = 1
let name = props.info.name //Uncaught TypeError: Cannot read property 'name' of undefined

使用可选链运算符,只需要在对象后边使用?.的方式访问属性即可,如果碰到null或undefined的值,返回undefined,并不会出现错误异常

1
2
let id = props?.query?.id       // id =1
let name = props?.info?.name // undefined

避免了以往采用的判断一个对象值是否存在,再去引用对象中属性的方法(props && props.query),层级深的时候,会写一长串代码

空值合并运算符

在声明变量时,想给变量一个默认值,我们采用 || 的方法去设置默认值。

1
2
let name = '王二'
let defaultName = name || '李三'

当name值为null或undefined时,defaultName为默认值李三,而这样的会过滤掉值为0,false,""的情况,被默认值所覆盖。
  以往,为了不覆盖此类值,还得单独写条件去判断。现在我们可以使用??操作符来代替||,这只允许在值为null或undefined时使用默认值。

1
2
3
4
5
6
7
let name
name = '' ?? '王二' // ''
name = '' || '王二' // 王二
name = false ?? '王二' // ''
name = false || '王二' // 王二
name = 0 ?? '王二' // ''
name = 0 || '王二' // 王二

使用#给class类添加私有变量

在最新提案中,可以使用#给class类添加私有变量,不需要使用闭包来隐藏不想暴露给外部的私有变量,具体使用如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
class Counter {
#number = 1
cumulative() {
this.#number++
}
getNumber() {
return this.#number++
}
}
let counter = new Counter()
counter.cumulative()
console.log(counter.getNumber()) // 2
console.log(counter.getNumber()) // 3
console.log(counter.#number) // Uncaught SyntaxError: Private field '#number' must be declared in an enclosing class

BigInt-任意精度整数

JS中Number类型只能安全的表示-(2^53-1)至 2^53-1 范围的值,超出这个范围的整数计算或者表示会丢失精度,我们可以用 BigInt 对象表示不在这个范围内的数。
  要定义 BigInt,可以像下面的码一样:

1
2
3
4
5
6
let a = BigInt(2)              // 2n
let b = BigInt('22222') // 22222n
let c = 123n // 123n
console.log(typeof a) // bigint
console.log(a + b) // 22224n
console.log(b / a) // 11111n

Number类型与BigInt类型比较

1
2
3
4
5
6
let a = 555n              
let b = 555
console.log(a === b) // false
console.log(a == b) // true
console.log(a > b) // false
console.log(b > a) // false

BigInt不能与内置Math对象一起使用。在数字与BigInt之间进行转换时必须小心,因为在将BigInt转换为数字时,BigInt的精度可能会丢失,反之亦然。

Promise.allSettled

Promise.allSettled()方法返回一个在所有给定的promise已被决议或被拒绝后决议的promise,并带有一个对象数组,每个对象表示对应的promise结果。

1
2
3
4
5
6
7
8
9
const promise1 = Promise.resolve(3);
const promise2 = new Promise((resolve, reject) => setTimeout(reject, 100, 'foo'))
Promise.allSettled([promise1, promise2]).then(results => {
results.forEach(result => {
console.log(result)
})
});
// {status: "fulfilled", value: 3}
// {status: "rejected", reason: "foo"}

import.meta

import.meta是一个给JavaScript模块暴露特定上下文的元数据属性的对象。它包含了这个模块的信息,比如说这个模块的URL。
  import.meta对象由一个关键字"import",一个点符号和一个meta属性名组成。通常情况下"import."是作为一个属性访问的上下文,但是在这里"import"不是一个真正的对象。

1
2
<script type="module" src="my-module.mjs"></script>
console.log(import.meta); // { url: "file:///home/user/my-module.mjs" }

它返回一个带有url属性的对象,指明模块的基本URL。也可以是外部脚本的URL,还可以是内联脚本所属文档的URL。


本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!