跳到主内容

JS从ES7到ES12的新特性

· 8分钟阅读
James

随着JS的发展越来越完善,官方也持续推进新的特性出来,给前端开发带来了简单,友好的开发体验,话不多说,本文总结了ES7-ES12各个版本出现新的特性

ES7

includes

求幂运算符(**)

求幂运算符(**)功能跟 Math.pow 一样,不同之处在于它接受 BigInt 作为操作数

2 ** 3   // 8
3 ** 2 // 9
3 ** 2.5 // 15.588457268119896
10 ** -1 // 0.1
NaN ** 2 // NaN

includes() 用来判断一个数组是否包含一个指定的值,返回一个 boolean 值

[1, 2, 3].includes(2);     // true
[1, 2, 3].includes(4); // false
[1, 2, 3].includes(3, 3); // false
[1, 2, 3].includes(3, -1); // true
[1, 2, NaN].includes(NaN); // true

indexOf的区别是,indexOf 返回索引,对 NaN 不生效

ES8

async 和 await

async 和 await 关键字是基于 Generator 函数的语法糖,可以使用同步的写法来实现异步的功能

const asyncReadFile = async function () {
const f1 = await getData('/userList');
const f2 = await readFile('/productList');
console.log(f1.data);
console.log(f2.data);
};

Object.getOwnPropertyDescriptors

返回一个对象所有自身属性的描述符,如果没有任何自身属性,则返回空对象。

Object.values()

Object.values() 方法返回一个对象所有可枚举属性值的数组,值的顺序与使用 for...in 循环的顺序相同

Object.values({a: 1, b: 2, c: 3});

Object.entries()

Object.entries() 方法返回一个对象自身可枚举属性的键值对数组,其排列与使用 for...in 循环遍历该对象时返回的顺序一致

Object.entries({a: 1, b: 2, c: 3}); // [["a", 1], ["b", 2], ["c", 3]]

String的padStart和padEnd方法

都是用来操作字符串

str.padStart(targetLength [, padString]) 可以指定字符串进行头部填充直到目标长度所形成的新字符串

str.padEnd(targetLength [, padString]) 可以指定字符串进行尾部填充直到目标长度所形成的新字符串

'hello'.padStart(10);         // "       hello"
'hello'.padStart(10, "foo"); // "foofoofhello"

'hello'.padEnd(10); // "hello "
'hello'.padEnd(10, "foo"); // "hellofoofoof"

Promise的finally方法

在 Promise 结束时,无论结果是 fulfilled 还是 rejected,都会执行指定的回调函数

promise
.then(result => { ... })
.catch(error => { ... })
.finally(() => { ... })

对象解构

Object.assign() 函数会触发 setters,而解构不会。

let { foo, bar } = { foo: "aaa", bar: "bbb" };

ES10

数组的flat和flatMap方法

flat() 将嵌套的数组拉平,返回一个新的数组

flatMap() 对数组每个成员执行一个函数操作后,再执行 flat() 方法,返回一个新的数组

const arr = [1, 2, 3, [1, 2, 3, 4, [2, 3, 4]]];
arr.flat(Infinity);
// [1, 2, 3, 1, 2, 3, 4, 2, 3, 4]

[2, 3, 4].flatMap((x) => [x, x * 2])
// [2, 4, 3, 6, 4, 8]

Object.fromEntries

Object.fromEntries() 把键值对列表转换为一个对象

Object.fromEntries() 结果与 Object.entries() 互逆

const obj = Object.fromEntries([['a', 0], ['b', 1]]); 
// { a: 0, b: 1 }
const map = new Map([['a', 1], ['b', 2], ['c', 3]]);
const obj = Object.fromEntries(map);
// { a: 1, b: 2, c: 3 }

String.trimStart和String.trimEnd

trimStart() 移除头部空格

trimEnd() 移除尾部空格

const foo = '   Hello world!   ';
console.log(foo.trimStart());
// "Hello world! ";
console.log(foo.trimEnd());
// " Hello world!";

ES11

String matchAll

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

const str = 'hello world hello kitty'
console.log(...str.matchAll(/hello/g))
// ['hello', index: 0, input: 'hello world hello kitty', groups: undefined] ['hello', index: 12, input: 'hello world hello kitty', groups: undefined]

BigInt

BigInt 是一种新的数字类型,它可以表示任意精度格式的整数

Promise.allSettled

Promise.allSettled() 方法返回一个在所有给定的 promise 都已经 fulfilledrejected 后的 promise,并带有一个对象数组,每个对象表示对应的 promise 结果。

??

空值合并操作符(??),当左侧的操作数为 null 或者 undefined 时,返回其右侧操作数,否则返回左侧操作数。

let user = {
u1: 0,
u2: false,
u3: null,
u4: undefined,
u5: '',
}
let u2 = user.u2 ?? '用户2'; // false
let u3 = user.u3 ?? '用户3'; // 用户3
let u4 = user.u4 ?? '用户4'; // 用户4
let u5 = user.u5 ?? '用户5'; // ''

可选链 ?.

可选链操作符(?.)允许读取位于连接对象链深处的属性的值,而不必明确验证链中的每个引用是否有效。?. 操作符的功能类似于 . 链式操作符,不同之处在于,在引用(null 或者 undefined)的情况下不会引起错误,该表达式短路返回值是 undefined。与函数调用一起使用时,如果给定的函数不存在,则返回 undefined

直接看代码比较容易理解

const nestedProp = obj?.['prop' + 'Name'];
let arrayItem = arr?.[42];

ES12

String的replaceAll方法

replaceAll() 方法返回一个新字符串,新字符串所有满足 pattern 的部分都已被 replacement 替换。pattern 可以是一个字符串或一个 RegExpreplacement 可以是一个字符串或一个在每次匹配被调用的函数。

'aabbcc'.replaceAll('b', '.'); // aa..cc
"aa123cc".replaceAll(/[\d]/g, "?"); // aa???cc

注意:replaceAll 如果参数是正则,必须指定全局匹配 (g)

Promise.any

Promise.any() 接收一个 promise数组,只要其中的一个 promise 成功,就返回那个已经成功的 promise。如果可迭代对象中没有一个 promise 成功,就返回一个失败的 promise

const pErr = new Promise((resolve, reject) => {
reject("总是失败");
});

const pSlow = new Promise((resolve, reject) => {
setTimeout(resolve, 500, "最终完成");
});

const pFast = new Promise((resolve, reject) => {
setTimeout(resolve, 100, "很快完成");
});

Promise.any([pErr, pSlow, pFast]).then((value) => {
console.log(value);
// pFast fulfils first
})
// 期望输出: "很快完成"

逻辑赋值运算符

a ||= b;
//等价于
a = a || (a = b);

a &&= b;
//等价于
a = a && (a = b);

a ??= b;
//等价于
a = a ?? (a = b);

数字分隔符