一、ES2022(ES13)
- 数组方法:
Array.prototype.at():方法接收一个整数值并返回该索引对应的元素,允许正数和负数。负整数从数组中的最后一个元素开始倒数。
[1, 2, 3].at(1)
// 2
[1, 2, 3].at(-1)
// 3
- WeakRefs:
WeakRef:让开发人员监视对象是否已被垃圾回收器释放。
二、ES2021 (ES12)
- 字符串方法:
String.prototype.replaceAll():将所有与正则表达式匹配的子字符串都替换为新的字符串。
const newStr = str.replaceAll(regexp|substr, newSubstr|function)
'aabbcc'.replaceAll('b', '.');
// 'aa..cc'
'aabbcc'.replaceAll(/b/, '.');
// TypeError: replaceAll must be called with a global RegExp
'aabbcc'.replaceAll(/b/g, '.');
// "aa..cc"
- Promise方法
Promise.any():方法接受一组 Promise 对象,并在其中任何一个 Promise 完成时返回该 Promise 的值。如果所有 Promise 都被拒绝,则返回一个 AggregateError。
const promises = [Promise.reject('ERROR A'), Promise.reject('ERROR B'), Promise.resolve('result')]
Promise.any(promises).then((value) => {
console.log('value: ', value)
}).catch((err) => {
console.log('err: ', err)
})
// value: result
const promises = [
Promise.reject('ERROR A'),
Promise.reject('ERROR B'),
Promise.reject('ERROR C'),
]
Promise.any(promises).then((value) => {
console.log('value:', value)
}).catch((err) => {
console.log('err:', err)
console.log(err.message)
console.log(err.name)
console.log(err.errors)
})
// err: AggregateError: All promises were rejected
// All promises were rejected
// AggregateError
// ["ERROR A", "ERROR B", "ERROR C"]
Promise.allSettled() 接受一组 Promise 对象,并返回一个 Promise,该 Promise 在所有 Promise 完成或拒绝后解决。与 Promise.all() 不同的是,Promise.allSettled() 不会提前拒绝 Promise。而是等待所有 Promise 完成,然后返回一个数组,其中包含每个 Promise 的状态和值。
- Logical assignment(逻辑或赋值)
现在,我们可以使用 a ||= b 语法来执行逻辑分配。这意味着如果变量 a 的值是 false,则将变量 b 的值分配给变量 a。
a ||= b
a || (a = b)
三、ES2020(ES11)
ES2020(也称为ES11)是JavaScript的一个新版本,它于2020年6月正式推出。以下是ES2020中的一些新语法特性:
- Nullish coalescing operator (??)空值合并运算符
这个运算符允许我们将两个值中的第一个“定义”值取出来。如果第一个值是 null 或 undefined,就返回第二个值。
const a = b ?? false
- Optional chaining operator (?.)可选链
这个运算符允许我们轻松地在属性链中访问嵌套的属性,而不用检查属性是否存在。如果在属性访问过程中遇到 undefined 或 null,它会短路并立即返回 undefined。
const a = b?.c?.d
- Dynamic import()
import() 允许我们在运行时异步导入模块。这使得我们可以按需加载代码,以满足性能和功能需求。
- BigInt
BigInt是一种新的基本数据类型,它提供了一种方法来表示大于 2^53 - 1 的整数。这原本是 Javascript 中可以用 Number 表示的最大数字。BigInt 可以表示任意大的整数。
可以用在一个整数字面量后面加 n 的方式定义一个 BigInt ,如:10n,或者调用函数 BigInt()(但不包含 new 运算符)并传递一个整数值或字符串值。
const theBiggestInt = 9007199254740991n;
const alsoHuge = BigInt(9007199254740991);
// ↪ 9007199254740991n
const hugeString = BigInt("9007199254740991");
// ↪ 9007199254740991n
const hugeHex = BigInt("0x1fffffffffffff");
// ↪ 9007199254740991n
const hugeBin = BigInt("0b11111111111111111111111111111111111111111111111111111");
// ↪ 9007199254740991n
它在某些方面类似于 Number ,但是也有几个关键的不同点:不能用于 Math 对象中的方法;不能和任何 Number 实例混合运算,两者必须转换成同一种类型。在两种类型来回转换时要小心,因为 BigInt 变量在转换成 Number 变量时可能会丢失精度。
BigInt 转换成Number
const x = 1n;
const y = Number(x.toString());
// y为1
四、ES2019(ES10)
- Array.flat()和Array.flatMap()
Array.flat() 方法使得我们可以轻松压平多维数组。Array.flatMap() 方法结合map()和flat()方法实现了对数组的映射和压平。元素是多层数组只能压平第一层。
const arr1 = [0, 1, 2, [3, 4]];
console.log(arr1.flat());
// Expected output: Array [0, 1, 2, 3, 4]
[1, 2, [[1, 2]]].flat()
// [1, 2, [1, 2]]
flatMap() 方法对数组中的每个元素应用给定的回调函数,然后将结果展开一级,返回一个新数组。它等价于在调用 map() 方法后再调用深度为 1 的 flat() 方法(arr.map(...args).flat()),但比分别调用这两个方法稍微更高效一些。
const arr = [1, 2, 3];
const result = arr.flatMap(x => [x, x * 2]); console.log(result); // [1, 2, 2, 4, 3, 6]
- String.prototype.trim() 和 String.prototype.trimStart() 和 String.prototype.trimEnd()
这两个方法分别允许我们从字符串的开头和结尾删除空格。这个功能在处理用户输入或从数据源中提取文本时非常有用。
const greeting = ' Hello world! ';
console.log(greeting.trimStart());
// Expected output: "Hello world! ";
console.log(greeting.trimEnd())
// ' Hello world!'
console.log(greeting.trim());
// 'Hello world!'
- Object.fromEntries()
Object.fromEntries() 方法接受一个由[key, value]对组成的数组,并返回一个包含这些键和值的新对象。这使得我们可以方便地将数组转换为一个对象。
const entries = [['a', 1], ['b', 2]]
Object.fromEntries(entries)
// {a: 1, b: 2}
五、ES2018(ES9)
- Async Iteration
ES9引入了异步迭代器(Async Iterators),使得我们可以对异步数据源(例如Promise、generator、WebSocket)进行迭代操作,并在每个迭代中等待异步操作完成。
- Promise.prototype.finally()
ES9在Promise对象上添加了finally()方法,这个方法始终执行,并且要么在Promise resolve时执行,要么在Promise reject时执行。
function checkMail() {
return new Promise((resolve, reject) => {
if (Math.random() > 0.5) {
resolve('Mail has arrived');
} else {
reject(new Error('Failed to arrive'));
}
});
}
checkMail()
.then((mail) => {
console.log(mail);
})
.catch((err) => {
console.error(err);
})
.finally(() => {
console.log('Experiment completed');
});
async () => {
try {
const result1 = await firstAsynchronousFunction();
const result2 = await secondAsynchronousFunction(result1);
console.log(result2);
} catch(err) {
throw new Error(`Something failed`);
} finally {
console.log(`All Tasks are Done`);
}
}
- RegExp named groups
在ES9中,正则表达式支持RegExp named groups。这使得我们可以通过名称而不是位置来捕获匹配的字符串,从而使正则表达式更加易于使用和维护。 RegExp命名分组是指能够为正则表达式中的一个子匹配分配一个名称。通过给子匹配分配一个名称,可以更方便地从表达式的结果中提取所需的数据。
在正则表达式中,可以使用括号将子匹配组合在一起。通过在括号内指定一个名称,可以将该子匹配分配给这个名称。语法如下:
/(?<name>pattern)/
// 其中,`name`是指定的名称,`pattern`是正则表达式模式。
// 可以通过`exec`函数获取匹配结果。可以使用`groups`属性来访问分组的结果,如:
const regex = /(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})/;
const match = regex.exec('2022-05-25');
六、ES8
- String padding
ES8允许我们在字符串填充方面变得更加灵活。我们现在可以使用String.padStart()和String.padEnd()方法来对字符串进行填充。
padStart(targetLength)
padStart(targetLength, padString)
'abc'.padStart(10); // " abc"
'abc'.padStart(10, "foo"); // "foofoofabc"
'abc'.padStart(6,"123465"); // "123abc"
'abc'.padStart(8, "0"); // "00000abc"
'abc'.padStart(1); // "abc"
padEnd(targetLength)
padEnd(targetLength, padString)
'abc'.padEnd(10); // "abc "
'abc'.padEnd(10, "foo"); // "abcfoofoof"
'abc'.padEnd(6, "123456"); // "abc123"
'abc'.padEnd(1); // "abc"
- Async functions
ES8引入了async functions,这是一种更加易于使用的异步代码编写方式。与Promise类似,async函数返回一个Promise对象,但它使用async和await关键字来简化异步代码的编写。
function resolveAfter2Seconds() {
return new Promise(resolve => {
setTimeout(() => {
resolve('resolved');
}, 2000);
});
}
async function asyncCall() {
console.log('calling');
const result = await resolveAfter2Seconds();
console.log(result);
// Expected output: "resolved"
}
asyncCall();
- Shared Memory and Atomics(共享内存和原子)
ES8通过 Shared Memory and AtomicsAPI 为JavaScript引入了多线程和共享内存的概念。这使得JavaScript更加适合高级计算和并发任务。 juejin.cn/post/684490…
七、ES7
ES7(也称为ES2016)是JavaScript的一个新版本,它于2016年6月正式推出。以下是ES7中的一些新语法特性:
- Array.includes()
ES7引入了Array.includes()方法,它可以用来检测数组中是否包含给定的值。 这个方法是indexOf()方法的更加直观和易于使用的替代品。
[1, 2, 3, 5].includes(1)
// true
[1, 2, 3, 4].indexOf(1)
// 1
- Exponentiation Operator
ES7引入了一个新的操作符:指数运算符(**)。这个操作符允许我们使用更简单和更可读的方式来计算一个数的幂。
2 ** 3
// 8
- Object.values() 和 Object.entries()
ES7允许我们使用Object.values()和Object.entries()方法获取对象的所有属性值和所有属性/值对。 这使得我们可以更快速方便地遍历对象属性。
Object.values([1, 2, 3, 5])
// [1, 2, 3, 5]
Object.entries({a: 1, b: 1})
// [['a', 1],['b', 1]]