编者按:本文作者奇舞团前端工程师郭文涛。
探索应用新技术能提升社会效率和降低成本。
该方法接收一个可迭代的对象,例如Array,其中每个成员都是Promise。仅在所有这些Promise状态都改变为rejected或resolved时,返回的promise的处理程序作为输入传递一个数组,每个promise的结果包含status字符创,当status为fulfilled, 且返回一个value,反之,当status为rejected返回会包含一个reason。
const sleep = (timeout) => { return new Promise((resolve, reject) => { setTimeout(() => { resolve("sleep finish!"); }, timeout); }); }; Promise.allSettled([ sleep(2000), Promise.reject(new Error("error")), ]).then((res) => { console.log("res", res); });
相关链接
https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Promise/allSettled
https://tc39.es/proposal-promise-allSettled/
https://www.npmjs.com/package/promise.allsettled
ES2020 globalThis 提供了一个标准的方式来获取不同环境下的全局 this 对象(也就是全局对象自身),所以不用担心运行环境。
globalThis.location === window.location; // true
https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/globalThis
语法:?.
减少访问深层对象时判断属性存不存在的问题。
const adventurer = { name: 'Alice', cat: { name: 'Dinah' } }; console.log(adventurer.dog?.name); // 输出undefined;adventurer.dog?.name等价于adventurer.dog && adventurer.dog.name console.log(adventurer.dog?.getName?.()); // undefined // 短路计算 let potentiallyNullObj = null; let x = 0; let prop = potentiallyNullObj?.[x++]; console.log(x); // 作为0的x将不会被递增,依旧输出0
注意: ?.不能用来赋值。
https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Operators/可选链
空值合并运算符(??)是一个逻辑运算符。当左侧操作数为 null 或 undefined 时,其返回右侧的操作数。否则返回左侧的操作数。
同理可以进行类似3 可选链操作符的短路操作。
https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Operators/Nullish_coalescing_operator
import.meta对象是由ECMAScript实现的,它带有一个null的原型对象。这个对象可以扩展,并且它的属性都是可写,可配置和可枚举的。
// index.js console.log(import.meta); // 打印出{url: "http://127.0.0.1:8099/html/2020-JavaScript/index.js"}
React中使用参考babel插件babel-plugin-syntax-import-meta。
https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Statements/import.meta
以前JavaScript中存储为整数的最大数量为pow(2, 53) - 1,ES2020 BigInt 是一种内置对象,它提供了一种方法来表示大于 253 - 1 的整数。BigInt 可以表示任意大的整数。
BitInt是在整数后面添加n的方式定义,或者用BitInt(*);
typeof 9007199254740991n === 'bigint'; // true typeof BitInt('1') === 'bigint' // true;
注意:
使用 Object 包装后, BigInt 被认为是一个普通 "object" :
typeof Object(1n) === 'object'; // true
当使用 BigInt 时,带小数的运算会被取整。
5n / 2n; // 2n
BigInt 和 Number 不是严格相等的,但是宽松相等的。
1n === 1; // false; 1n == 1; // true;
BigInt 和 Number 混在一个数组中可以正常排序。
Object 包装的 BigInts 使用 object 的比较规则进行比较,只用同一个对象在比较时才会相等。
0n === Object(0n); // false Object(0n) === Object(0n); // false const o = Object(0n); o === o // true
BigInt 在需要转换成 Boolean 的时表现跟 Number 类似。
由于在 Number 与 BigInt 之间进行转换会损失精度,因而建议仅在值可能大于253 时使用 BigInt 类型,并且不在两种类型之间进行相互转换。
对任何 BigInt 值使用 JSON.stringify() 都会引发 TypeError,因为默认情况下 BigInt 值不会在 JSON 中序列化。可以手动实现:
JSON.stringify(BigInt('0')); // Uncaught TypeError: Do not know how to serialize a BigInt BigInt.prototype.toJSON = function() { return this.toString(); } JSON.stringify(BigInt('0')); // '"0"'
https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/BigInt
关键字import可以像调用函数一样来动态的导入模块, 这种方式会返回一个promise。
if(flag) { import('./module.js').then(fn => { fn.say(); }) } // 也可以用async/await if(flag) { const fn = await import('./module.js'); fn.say(); }
https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Statements/import
私有实例字段 是通过# names句型(读作“哈希名称”)声明的,访问和声明时需要 带着#。只能在内部使用。
class Cat { #name = 'tom'; getName() { console.log(this.#name); } } const cat = new Cat(); cat.getName(); // tom cat.#name; // Uncaught SyntaxError: Private field '#name' must be declared in an enclosing class class Pig extends Cat {} const pig = new Pig(); pig.getName(); // tom pig.#name; // Uncaught SyntaxError: Private field '#name' must be declared in an enclosing class
私有实例方法, 语法类似都是#names。
class ClassWithPrivateMethod { #privateMethod = () => { return "hello world"; }; getPrivateMessage() { return this.#privateMethod(); } } const instance = new ClassWithPrivateMethod(); console.log(instance.getPrivateMessage()); // hello world console.log(instance.#privateMethod()); // SyntaxError: Private field '#privateMethod' must be declared in an enclosing class
静态私有字段
class ClassWithPrivateStaticField { static #PRIVATE_STATIC_FIELD; static publicStaticMethod() { ClassWithPrivateStaticField.#PRIVATE_STATIC_FIELD = 42; return ClassWithPrivateStaticField.#PRIVATE_STATIC_FIELD; } } console.log( ClassWithPrivateStaticField.publicStaticMethod() === ClassWithPrivateStaticField.#PRIVATE_STATIC_FIELD ); // SyntaxError: Private field '#PRIVATE_STATIC_FIELD' must be declared in an enclosing class
静态私有方法
class ClassWithPrivateStaticMethod { static #privateStaticMethod = () => { return 42; }; static publicStaticMethod() { return ClassWithPrivateStaticMethod.#privateStaticMethod(); } } console.log(ClassWithPrivateStaticField.publicStaticMethod() === 42); // true
https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Classes/Class_elements
语法: str.matchAll(regexp)
给定一个字符串和一个正则表达式,matchAll()方法返回所有与该字符串匹配正则表达式的结果的迭代器,包括捕获groups。
let regexp = /t(e)(st(\d?))/g; let str = 'test1test2'; let array = [...str.matchAll(regexp)]; console.log(array[0]); // ["test1", "e", "st1", "1"] console.log(array[1]); // ["test2", "e", "st2", "2"] let array2 = str.match(regexp); console.log(array2); // [ 'test1', 'test2' ]
https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/String/matchAll
ECMA规范未指定for (x in y) 应按哪个顺序运行。即使以前浏览器自己实现了一致的顺序,但ES2020已正式对其进行标准化。
在JavaScript中可以使用一下语法:
import * as utils from './module.js'; // 但是,不export存在对称语法, 但是现在已支持 export * as utils from './module.js'; // 等效于 import * as utils from './utils.mjs'; export { utils };
欢迎留言指正,或罗列更多的ES新特性。
参考文章
https://v8.dev/features/tags/es2020
https://developer.mozilla.org/zh-CN
《奇舞周刊》是360公司专业前端团队「奇舞团」运营的前端技术社区。关注公众号后,直接发送链接到后台即可给我们投稿。