ES7+新语法

282 阅读7分钟

一、ES2022(ES13)

  1. 数组方法:
  • Array.prototype.at():方法接收一个整数值并返回该索引对应的元素,允许正数和负数。负整数从数组中的最后一个元素开始倒数。
[1, 2, 3].at(1)
// 2
[1, 2, 3].at(-1)
// 3
  1. WeakRefs:
  • WeakRef:让开发人员监视对象是否已被垃圾回收器释放。

二、ES2021 (ES12)

  1. 字符串方法:
  • 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"
  1. 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 的状态和值。

  1. Logical assignment(逻辑或赋值)

现在,我们可以使用 a ||= b 语法来执行逻辑分配。这意味着如果变量 a 的值是 false,则将变量 b 的值分配给变量 a。

a ||= b
a || (a = b)

三、ES2020(ES11)

ES2020(也称为ES11)是JavaScript的一个新版本,它于2020年6月正式推出。以下是ES2020中的一些新语法特性:

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

这个运算符允许我们将两个值中的第一个“定义”值取出来。如果第一个值是 null 或 undefined,就返回第二个值。

const a = b ?? false
  1. Optional chaining operator (?.)可选链

这个运算符允许我们轻松地在属性链中访问嵌套的属性,而不用检查属性是否存在。如果在属性访问过程中遇到 undefined 或 null,它会短路并立即返回 undefined。

const a = b?.c?.d
  1. Dynamic import()

import() 允许我们在运行时异步导入模块。这使得我们可以按需加载代码,以满足性能和功能需求。

  1. 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)

  1. 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]
  1. 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!'
  1. Object.fromEntries()

Object.fromEntries() 方法接受一个由[key, value]对组成的数组,并返回一个包含这些键和值的新对象。这使得我们可以方便地将数组转换为一个对象。

const entries = [['a', 1], ['b', 2]]
Object.fromEntries(entries)
// {a: 1, b: 2}

五、ES2018(ES9)

  1. Async Iteration

ES9引入了异步迭代器(Async Iterators),使得我们可以对异步数据源(例如Promise、generator、WebSocket)进行迭代操作,并在每个迭代中等待异步操作完成。

  1. 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`);
  }
}

  1. 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');

image.png

六、ES8

  1. 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"
  1. 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();
  1. Shared Memory and Atomics(共享内存和原子)

ES8通过 Shared Memory and AtomicsAPI 为JavaScript引入了多线程和共享内存的概念。这使得JavaScript更加适合高级计算和并发任务。 juejin.cn/post/684490…

七、ES7

ES7(也称为ES2016)是JavaScript的一个新版本,它于2016年6月正式推出。以下是ES7中的一些新语法特性:

  1. Array.includes()

ES7引入了Array.includes()方法,它可以用来检测数组中是否包含给定的值。 这个方法是indexOf()方法的更加直观和易于使用的替代品。

[1, 2, 3, 5].includes(1)
// true
[1, 2, 3, 4].indexOf(1)
// 1
  1. Exponentiation Operator

ES7引入了一个新的操作符:指数运算符(**)。这个操作符允许我们使用更简单和更可读的方式来计算一个数的幂。

2 ** 3
// 8
  1. 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]]