Предисловие

ES6 был предложен в 2015 году, по этой логике ES2023 следует называть ES14, во избежание путаницы мы будем использовать год для названия. Вспоминая, когда я в последний раз обращал внимание на стандарт ES, вы все еще оставались на ES6? Чтобы не отставать от стандарта ES, давайте посмотрим, какие новые функции были добавлены за последние годы.

ES2023

Предложения, которые будут завершены в 2023 году

Возвращает копию при изменении массива

Array и TypedArray имеют множество способов (таких как сортировка/объединение и т. д.) для изменения самого массива, например:

const array = [3, 2, 1];
const sortedArray = array.sort();
// [1, 2, 3]
console.log(sortedArray);
// The original array also becomes [1, 2, 3]
console.log(array);

Если вы не хотите менять сам массив, вы можете сделать это:

const array = [3, 2, 1];
const sortedArray = array.toSorted();
// [1, 2, 3]
console.log(sortedArray);
// The original array keep [3, 2, 1]
console.log(array);

К подобным методам относятся:

T.prototype.toReversed() -> T
T.prototype.toSorted(compareFn) -> t
T.prototype.toSpliced(start, deleteCount, ...items) -> T
T.prototype.with(index, value) -> T

reverse/sort/splice можно еще понять, что такое for? Просто посмотрите на пример, чтобы понять:

const array = [1, 2, 3];
const newArray = array.with(1, false);
// [1, false, 3]
console.log(newArray);
// The original array keep [1, 2, 3]
console.log(array);

WeakMap поддерживает символ в качестве ключа

WeakMap изначально поддерживал только ключи типа object, но теперь поддерживает тип Symbol в качестве ключа.

const weak = new WeakMap();
weak.set(Symbol('symbol1'), {});

Синтаксис хеш-банга

Hashbang, также называемый Shebang, представляет собой #! последовательность символов, состоящая из знаков решетки и восклицательных знаков, указывающая, какой интерпретатор использовать для выполнения этого файла:

// hashbang.js
#!/usr/bin/env node
console.log('hashbang');

// nohashbang.js
console.log('no hashbang')

В терминальном выполнении без Hashbang вам нужно использовать команду node для выполнения:

Смотри из-за хвоста

В findLast / findLastIndex задействованы две функции.

const array = [1, 2, 3]
array.findLast(n => n.value % 2 === 1); 
array.findLastIndex(n => n.value % 2 === 1); 

ES2022

Цепочка исключений

Глядя непосредственно на пример, вы можете получить err1 через err0.cause; Если это исключение повторяется много раз, это происходит через err1.cause.cause…. Вы можете получить все соответствующие исключения.

function willThrowError() {
    try {
        // do something
    } catch (err0) {
        throw new Error('one error', { cause: err })
    }
}
try {
    willThrowError()
} catch (err1) {
  // You can get err0 through err1.caus
}

Блок статического кода класса

Блоки статического кода для реализации сложной логики инициализации статического свойства/метода:

// When there is no static code block, 
// the initialization editor is separate from the class definition
class C {
  static x = ...;
  static y;
  static z;
}
try {
  const obj = doSomethingWith(C.x);
  C.y = obj.y
  C.z = obj.z;
}
catch {
  C.y = ...;
  C.z = ...;
}
// Using static code blocks, the code logic is more convergent
class C {
  static x = ...;
  static y;
  static z;
  static {
    try {
      // Here this represents C not an instance of C
      const obj = doSomethingWith(this.x);
      this.y = obj.y;
      this.z = obj.z;
    }
    catch {
      this.y = ...;
      this.z = ...;
    }
  }
}

Также есть особая возможность: доступ к личным свойствам.

let getPrivateField;
class D {
    #privateField;
    constructor(v) {
        this.#privateField = v;
    }
    static {
        getPrivateField = (d) => d.#privateField;
    }
}
getPrivateField(new D('private value'));
// → private value

Object.hasOwn

Мы часто видим такое использование, особенно в библиотеках с открытым исходным кодом:

let hasOwnProperty = Object.prototype.hasOwnProperty
if (hasOwnProperty.call(object, "foo")) {
  console.log("has property foo")
}

Если вы используете Object.hasOwn, вы можете упростить до:

if (Object.hasOwn(object, "foo")) {
  console.log("has property foo")
}

.at возвращает элемент указанного индекса

Индексируемые типы (String/Array/TypedArray) могут считывать элементы указанного индекса через at и поддерживать передачу отрицательных чисел.

// return 4
[1, 2, 3, 4].at(-1)

Определить, существует ли частная собственность

Об этом можно судить по ключевому слову in

class C {
    #brand = 0;
  
    static isC(obj: C) {
      return #brand in obj;
    }
  }

Ожидание верхнего уровня

Вам не нужен асинхронный пакет, вы также можете использовать ожидание, например:

function fn() {
    return Promise.resolve();
}
// Previously required to implement via IIFE
(async function () {
    await fn();
})();
// After supporting top-level await, you can directly call
await fn();

Нарезка регулярных выражений

Путем обычного сопоставления мы можем получить только совпадающие строки, и мы можем получить положение этих строк в исходной строке, нарезая

const re1 = /a+(z)?/d;
const s1 = "xaaaz";
const m1 = re1.exec(s1);

ES2021

Числовой разделитель

Если числа длиннее, читаемость плохая, а разделитель _ может улучшить читаемость:

// 1000000
console.log(1_000_000)
// As long as the delimiter is not the first and last digit of the number,
// it is valid in any position 1_000000000_1_2_3
1_000000000_1_2_3

Назначение логического оператора

Это похоже на назначение арифметических операторов, но логические операторы также будут иметь возможности короткого замыкания, которые можно сравнивать друг с другом:

// arithmetic operator
let x = 1;
// x is 2
x += 1;
// Logical Operators
let x = 1;
// x is still 1, because x is a true value,
// so it is short-circuited, which is equivalent to x = 1 || 3
x ||= 3;

Слабая ссылка

Слабые ссылки, которые позволяют вам ссылаться на объект, не предотвращая сборку мусора.

let obj = { name: 'obj1' };
let weakRef = new WeakRef(obj);
// Get the referenced object
// If the reference object is recycled, it will get undefined
weakRef.deref();

Обещание.любое

Сравните это с несколькими другими функциями.

Обещание.любое

Пока один вход разрешается, он разрешается:

Promise.any([
  Promise.reject('reject 1'),
  Promise.reject('reject 2'),
  Promise.reject('reject 3'),
  Promise.resolve('1'),
  Promise.resolve('2'),
]).then(
  first => {
    // As long as there is a resolve, it will be executed here
    // prints 1
    console.log(first);
  },
  error => {
    // Only come here when all reject
    console.log(error);
  },
);

Promise.allSettled

Независимо от того, является ли введенное обещание отклонением или разрешением, оно сводится к тому времени.

Promise.allSettled([
  Promise.resolve('1'),
  Promise.resolve('2'),
  Promise.reject('e1'),
  Promise.resolve('3'),
  Promise.resolve('4'),
])
  .then(res => {
    console.log('then', res);
  });

Обещание.все

Пока есть отказ, значит, отказывают. Следующий пример подходит для catch:

Promise.all([
  Promise.resolve('1'),
  Promise.resolve('2'),
  Promise.reject('e1'),
  Promise.resolve('3'),
])
  .then(res => {
    console.log('then', res);
  })
  .catch(err => {
    // print catch e1
    console.log('catch', err);
  });

Обещание.гонка

Если есть отклонение (или разрешение), то отклонение (или разрешение)

function delay(type: 'resolve' | 'reject', timeout: number) {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      if (type === 'reject') {
        reject(type);
      } else {
        resolve(type);
      }
    }, timeout);
  });
}
// print then resolve
Promise.race([delay('resolve', 1000), delay('reject', 2000)])
  .then(res => {
    console.log('then', res);
  })
  .catch(err => {
    console.log('catch', err);
  });
  
 // print catch reject
Promise.race([delay('resolve', 2000), delay('reject', 1000)])
  .then(res => {
    console.log('then', res);
  })
  .catch(err => {
    console.log('catch', err);
  });
String.prototype.replaceAll

Заменить все совпадающие строки

// 12c12d12
'abcabdab'.replaceAll('ab', '12')
// 12cabdab
'abcabdab'.replace('ab', '12')

ES2020

импорт.мета

Предоставляет метаинформацию модуля, связанного с хостом.

Оператор слияния с нулевым значением

Правый операнд возвращается, только если левый операнд равен нулю или не определен

// "default"
let a = null || "default"
// "default"
let a = null ?? "default"
// "default"
let a = "" || "default"
// ""
let a = "" ?? "default"
// "default"
let a = 0 || "default"
// 0
let a = 0 ?? "default"

Дополнительная цепь

Смотрите прямо на код

// without optional chaining
const street = user.address && user.address.street;
// optional chaining
const street = user.address?.street

BigInt

Можно представить число больше 2 в степени 53 (наибольшее число, которое может представлять тип js Number).

// Add an n at the end of the number
const theBiggestInt = 9007199254740991n;
// Or call the BigInt constructor directly
const alsoHuge = BigInt(9007199254740991);

Импортировать()

Модули загружаются динамически во время выполнения.

String.prototype.matchAll

match может возвращать только совпадающие строки, но не информацию о группе; matchAll может возвращать совпадающие строки вместе с информацией о группе.

Краткое содержание

ES2016~ES2019 не будут перечислены один за другим, все должны быть с ним знакомы. Если есть неясные особенности, пожалуйста, оставьте сообщение для связи.

Ссылка

github.com/tc39/propos…

Дополнительные материалы на PlainEnglish.io.

Подпишитесь на нашу бесплатную еженедельную рассылку новостей. Подпишитесь на нас в Twitter, LinkedIn, YouTube и Discord .

Заинтересованы в масштабировании запуска вашего программного обеспечения? Ознакомьтесь с разделом Схема.