ES2020 新特性详解:可选链、空值合并与 BigInt 等核心更新

作者:函数茶馆

时间:2026-10-23

浏览:174

本文详解 ES2020 (ECMAScript 2020) 引入的七大核心新特性。重点解析可选链操作符(?.)简化嵌套对象访问,空位合并操作符(??)精准处理默认值,以及 Promise.allSettled 确保异步任务状态获取。同时涵盖动态 import() 实现按需加载、BigInt 支持超大整数计算、String.prototype.matchAll 高效正则匹配及 globalThis 统一全局对象访问,助力开发者提升代码安全性与性能。

文章目录

ES2020 概述与前言

引言部分

ES2020 即 ECMAScript 2020 年度版本。相较于 ES6 (ES2015) 的大规模更新,该版本特性较少,但仍包含诸多实用功能。欲查阅更多高质量内容,请访问我的博客。

本文通过简洁的代码示例解析 ES2020 新特性,旨在帮助读者快速理解新功能,无需复杂阐述。

可选链操作符 (Optional Chaining)

可选链操作符(Optional Chaining)

可选链机制允许在访问多层级对象属性时,免除繁琐的前置校验步骤。

开发中访问深层嵌套对象属性时,常遭遇臭名昭著的错误Uncaught TypeError: Cannot read property...,此类错误会导致程序中断运行。

ES2020 概述与前言

因此,需修改代码以处理属性链中可能出现的 undefined 对象,例如:


let nestedProp = obj && obj.first && obj.first.second;

在访问 obj.first.second 前,必须确保 obj 及 obj.first 非 null(且非 undefined)。

借助可选链式调用,可大幅简化此类繁琐的前置校验,同时提升安全性:


let nestedProp = obj?.first?.second;

若 obj 或 obj.first 为 null/undefined,表达式将执行短路计算并直接返回 undefined。

可选链操作符的浏览器支持情况如下:

ES2020 概述与前言

空位合并操作符 (Nullish Coalescing Operator)

空位合并操作符(Nullish coalescing Operator)

查询属性时,常需为缺失属性设置默认值,常见方式如下:


let c = a ? a : b // 方式1
let c = a || b // 方式2

上述方式存在明显缺陷,即会覆盖所有假值(如 0、''、false),而这些值在某些场景下可能是有效输入。


let x = {
 profile: {
  name: '浪里行舟',
  age: ''
 }
}
console.log(x.profile.age || 18) //18

前述示例中,age 属性为空字符串却被视为假值。为此,ES2020 引入空位合并操作符(??)。当 ?? 左侧表达式求值为 undefined 或 null 时,返回右侧默认值。


let c = a ?? b;
// 等价于let c = a !== undefined && a !== null ? a : b;

示例代码如下:


const x = null;
const y = x ?? 500;
console.log(y); // 500
const n = 0
const m = n ?? 9000;
console.log(m) // 0

空位合并操作符的浏览器支持情况如下:

ES2020 概述与前言

Promise.allSettled 异步处理

Promise.allSettled

Promise.all 具备并发执行异步任务的能力,但其最大缺陷在于:若参数中任一 promise 为 reject 状态,整个 Promise.all 调用将立即终止,并返回一个 reject 状态的 Promise 对象。


const promises = [
 Promise.resolve(1),
 Promise.resolve(2),
 Promise.reject('error')
];
 
 
Promise.all(promises)
 .then(responses => console.log(responses))
 .catch(e => console.log(e)) // "error"

假设存在如下场景:页面包含三个区域,分别对应三个独立接口数据。使用 Promise.all 并发请求这三个接口时,若任一接口异常(状态为 reject),将导致三个区域数据均无法显示。此状况难以接受,而 Promise.allSettled 的出现恰好解决了这一痛点:


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'
  })
 )
})

Promise.allSettled 与 Promise.all 类似,参数接受 Promise 数组,返回新 Promise。其唯一区别在于不进行短路处理,即当所有 Promise 处理完毕后,无论成功与否,均可获取每个 Promise 的状态。

Promise.allSettled 的浏览器支持情况如下:

ES2020 概述与前言

String.prototype.matchAll 正则匹配

String.prototype.matchAll

若正则表达式在字符串中存在多个匹配,通常需使用 g 或 y 修饰符,并在循环中逐一提取。


function collectGroup1 (regExp, str) {
 const matches = []
 while (true) {
  const match = regExp.exec(str)
  if (match === null) break
  matches.push(match[1])
 }
 return matches
}
console.log(collectGroup1(/"([^"]*)"/g, `"foo" and "bar" and "baz"`))
// [ 'foo', 'bar', 'baz' ]

值得注意的是,若无 /g 修饰符,.exec() 仅返回第一个匹配。现通过 String.prototype.matchAll 方法,可一次性提取所有匹配结果。


function collectGroup1 (regExp, str) {
 let results = []
 for (const match of str.matchAll(regExp)) {
  results.push(match[1])
 }
 return results
}
console.log(collectGroup1(/"([^"]*)"/g, `"foo" and "bar" and "baz"`))
// ["foo", "bar", "baz"]

上述代码中,string.matchAll(regex) 返回遍历器,故可使用 for...of 循环提取。

String.prototype.matchAll 的浏览器支持情况如下:

ES2020 概述与前言

Dynamic import 动态导入

Dynamic import

当前前端打包资源日益庞大,应用初始化时无需加载全部逻辑资源。为提升首屏渲染速度,常采用动态导入(按需加载)模块,如懒加载图片,从而优化应用性能。

按需加载逻辑资源通常在特定事件回调中执行:


el.onclick = () => {
 import('/modules/my-module.js')
  .then(module => {
   // Do something with the module.
  })
  .catch(err => {
   // load error;
  })
}

import() 可用于 script 脚本中,import(module) 函数可在任意位置调用,并返回解析为模块对象的 Promise。

此种使用方式同样支持 await 关键字。


let module = await import('/modules/my-module.js');

通过动态导入代码,可减少应用加载时间,并尽可能快地向用户返回内容。

Dynamic import 的浏览器支持情况如下:

ES2020 概述与前言

BigInt 大整数支持

BigInt

JavaScript 在数学运算方面存在局限,仅能安全表示-(2^53-1)至 2^53-1 范围内的值,即Number.MIN_SAFE_INTEGER 至Number.MAX_SAFE_INTEGER。超出此范围的整数计算或表示将丢失精度。


var num = Number.MAX_SAFE_INTEGER; // -> 9007199254740991
 
 
num = num + 1; // -> 9007199254740992
 
 
// 再次加 +1 后无法正常运算
num = num + 1; // -> 9007199254740992
 
 
// 两个不同的值,却返回了true
9007199254740992 === 9007199254740993 // -> true

为此,BigInt 应运而生,作为第7个原始类型,支持安全的大数整型计算。可在 BigInt 上使用与普通数字相同的运算符,如 +, -, /, *, % 等。

创建 BigInt 类型值十分简便,只需在数字后添加 n 即可,例如 123 变为 123n。亦可使用全局方法 BigInt(value) 进行转换,参数 value 为数字或数字字符串。


const aNumber = 111;
const aBigInt = BigInt(aNumber);
aBigInt === 111n // true
typeof aBigInt === 'bigint' // true
typeof 111 // "number"
typeof 111n // "bigint"

只要在数字末尾添加 n,即可正确计算大数:


1234567890123456789n * 123n;
// -> 151851850485185185047n

然而存在一个问题:在大多数操作中,BigInt 与 Number 不可混合使用。比较 Number 和 BigInt 是允许的,但不可将它们相加。


1n < 2 
// true
 
 
1n + 2
// Uncaught TypeError: Cannot mix BigInt and other types, use explicit conversions

BigInt 的浏览器支持情况如下:

ES2020 概述与前言

globalThis 全局对象访问

globalThis

globalThis 是一种获取全局 this 的全新标准方法。此前开发者通过以下方式获取:

  • 全局变量 window:经典的全局对象获取方法,但在 Node.js 和 Web Workers 中不可用。
  • 全局变量 self:通常仅在 Web Workers 和浏览器中生效,不支持 Node.js。部分开发者通过判断 self 是否存在来识别代码运行环境(Web Workers 或浏览器)。
  • 全局变量 global:仅在 Node.js 中生效。

过去获取全局对象,可通过一个全局函数:


// ES10之前的解决方案
const getGlobal = function(){
 if(typeof self !== 'undefined') return self
 if(typeof window !== 'undefined') return window
 if(typeof global !== 'undefined') return global
 throw new Error('unable to locate global object')
}
 
 
// ES10内置
globalThis.Array(0,1,2) // [0,1,2]
 
 
// 定义一个全局对象v = { value:true } ,ES10用如下方式定义
globalThis.v = { value:true }

globalThis 旨在提供一种标准化方式访问全局对象。使用 globalThis 后,可在任意上下文、任意时刻获取全局对象。

若运行环境为浏览器,globalThis 指向 window;若在 Node 环境中,globalThis 指向 global。因此,无需再考虑不同环境差异。


// worker.js
globalThis === self
// node.js
globalThis === global
// browser.js
globalThis === window

新提案规定,Object.prototype 必须位于全局对象的原型链中。以下代码在最新浏览器中已返回 true:


Object.prototype.isPrototypeOf(globalThis); // true

globalThis 的浏览器支持情况如下:

ES2020 概述与前言

参考资料与结语

参考文章

TC39 Proposals

MDN文档

种草 ES2020 新特性

ES2020 Features in simple examples

New Features In ES2020 You Should Check

5 ECMAScript Proposals To Look Out For In ES2020

以上为本文全部内容,希望对各位学习有所帮助,也希望大家多多支持本站。

实用工具推荐

电子包浆

绿化、压缩、噪点和虚拟水印,自由调节做旧程度。

使用 ›
图片压缩

选择画质和输出格式,预览压缩前后的大小。

使用 ›
相关文章