随着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
都已经fulfilled
或rejected
后的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
可以是一个字符串或一个 RegExp
, replacement
可以是一个字符串或一个在每次匹配被调用的函数。
'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);