ECMAScript 新特性

741 阅读3分钟

ES2021

Promise.any()

接收一个Promise实例数组,返回一个新的Promise实例。Promise实例数组中有一个fulfilled,新实例fulfilled;所有实例rejected,新实例rejected。本质上,这是一个与Promise.all() 完全相反的方法。

Promise.any(promises)
    .then(value => {
		// 任何一个 fulfilled, value 是 第一个 fulfilled value.
    	console.log(value)
    })
	.catch(errors => {
    	// 所有的都 rejected, errors 是所用 rejected reson 的集合
    	console.log(errors)
    })

兼容性:书写该文章时,处于TC39 Stage4IENodejs Opera不支持,其他新版浏览器支持。详见MDN

String.prototype.replaceAll()

replace()一样,不修改调用的字符串,返回新的字符串。但所有满足pattern的部分都回被替换成replacement

// 第一个参数,如果使用`regExp`, 必须设置全局标识 `g`。 否则会 `TypeError`。
const newStr = str.replaceAll(regexp|substr, newSubstr|function)
'aabbcc'.replace('b', '_')  // 'aa_bcc'
'aabbcc'.replaceAll(/b/g, '.'); // 'aa..cc'  效果同 replace

详细讲解:ECMAScript 6 入门

兼容性:书写该文章时,IENodejs 不支持,其他新版浏览器支持。详见MDN

ES2020

可选链操作符 ?. (Optional chaining)

如果引用nullundefined,表达式短路(不继续往下执行),返回值undefined

obj?.prop
obj?.[expr]
arr?.[index]
func?.(args)
// 以前
let nestedProp = obj.first && obj.first.second;
// 以后
let nestedProp = obj.first?.second;
let result = someInterface.customMethod?.();
// 禁止以下写法
// 构造函数
new a?.()
new a?.b()
// 链判断运算符的右侧有模板字符串
a?.`{b}`
a?.b`{c}`
// 链判断运算符的左侧是 super
super?.()
super?.foo
// 链运算符用于赋值运算符左侧
a?.b = c

详细讲解:ECMAScript 6 入门

兼容性:IEFirefox for Android 、 Opera for Android 不支持。详见MDN

空值合并运算符?? ( Nullish coalescing operator )

当左侧的操作数为nullundefined时,返回右侧操作数,否则返回左操作数。

leftExpr ?? rightExpr
// 以前
const foo = foo || []; // foo 为 null, undefined, false, 0, '', NaN
const foo = (foo === null || foo === undefined) ? [] : foo;
// 以后
const foo = foo ?? [];
// 不能与 && 或 || 共用
null || undefined ?? "foo"; // 抛出 SyntaxError
// 用括号来显式表明运算优先级,可以用
(null || undefined ) ?? "foo"; // 返回 "foo"

详细讲解:ECMAScript 6 入门

兼容性:IEFirefox for Android 、 Opera for Android 不支持。详见MDN

Promise.allSettled()

接收一个Promise实例数组,返回一个新的Promise实例。所有实例都返回,无论成功或失败,新实例fulfilled

Promise.allSettled(promises)
	.then(result => {
    	// result 如下所示
	    // [
        //    { status: 'fulfilled', value: 42 },
        //    { status: 'rejected', reason: -1 }
        // ]
	})

兼容性:IEFirefox for Android 不支持。详见MDN

export 和 import 复合写法补充

// 以前
import * as ns from "mod";
export {ns};
// 以后
export * as ns from "mod";

export 动态导入

使用场景:(勿滥用)

  • 模块被使用的可能性很低,但模块较大,静态导入明显降低加载速度、占用内存。
  • 模块需要异步获取
import('/modules/my-module.js')
  .then((module) => {
    // Do something with the module.
  });
  
let module = await import('/modules/my-module.js');

globalThis

在语言标准的层面,引入globalThis作为顶层对象 。 任何环境下,globalThis都是存在的。

以前,不同JS环境获取顶层对象的方式不同:
    web中,window、self、frames。
    web worker中,self。
    node中,global.
this使用:
  全局环境,this 返回 顶层对象。
  node 模块中 this 返回当前模块。
  ES6模块、严格模式,this 返回 undefined.
	

兼容性:IE不支持,nodejs 12.0以上支持。详见MDN

BigInt 数据类型

ECMAScript 的第八种数据类型。 BigInt 只用来表示整数,没有位数的限制,任何位数的整数都可以精确表示。

typeof 1n === 'bigint'; // true
typeof BigInt('1') === 'bigint'; // true
// 支持 BingInt 之间的 +、*、-、**、%,不可跨类型
// 带小数的运算回被取整。
const rounded = 5n / 2n;  // 2n, not 2.5n
// 支持与 Number 比较,宽松相等
0n === 0 //  false
0n == 0 //  true
2n > 2 //  false
// 转换成 Boolean 值,与 Number 类似
0n && 12n //  0n

//对任何 BigInt 值使用 JSON.stringify() 都会引发 TypeError

兼容性:IE不支持。详见MDN

String.prototype.matchAll()

返回一个包含所有匹配正则表达式的结果及分组捕获组的迭代器。

str.matchAll(regexp)
const regexp = /t(e)(st(\d?))/g;
const str = 'test1test2';
const array = [...str.matchAll(regexp)];
console.log(array[0], arr[1]);
// ["test1", "e", "st1", "1", index: 0, input: "test1test2"]
// ["test2", "e", "st2", "2", index: 5, input: "test1test2"]

详细讲解:ECMAScript 6 入门

兼容性:IE不支持。详见MDN