Новые функции ES2020

JavaScript ECMAScript 6

предисловие

ES2020 — это версия ECMAScript 2020 года. В этом выпуске не так много новых функций, как в ES6 (ES2015). Но также добавлено много интересных и полезных функций.

В этой статье представлены новые функции ES2020 с простыми примерами кода. Таким образом, вы можете быстро понять эти новые функции без сложных объяснений.Больше качественных Статьи Пожалуйста, удариБлог GitHub

Необязательная цепочка

дополнительная цепочкаЭто устраняет необходимость в избыточных предварительных проверках при запросе объектов с несколькими уровнями.

В повседневной разработке, когда вам нужно получить доступ к свойствам, вложенным в несколько уровней внутри объекта, вы можете получить пресловутую ошибкуUncaught TypeError: Cannot read property..., такая ошибка приводит к остановке работы всей программы.

Итак, вам нужно изменить свой код, чтобы он обрабатывал все возможные неопределенные объекты в цепочке свойств, например:

let nestedProp = obj && obj.first && obj.first.second;

Прежде чем обращаться к obj.first.second, убедитесь, что значения obj и obj.first не равны нулю (и не являются неопределенными).

С необязательными цепочками вызовов подобные утомительные операции предварительной проверки могут быть значительно упрощены и более безопасны:

let nestedProp = obj?.first?.second;

Если obj или obj.first имеет значение null/undefined, выражение замкнется и вернет значение undefined.

Дополнительная поддержка оператора цепочки:

Нулевой объединяющий оператор

Когда мы запрашиваем атрибут, мы часто устанавливаем значение по умолчанию без атрибута, например, двумя способами:

let c = a ? a : b // 方式1
let c = a || b // 方式2

Оба эти методы имеют очевидный недостаток, что они перезаписывают все ложные значения, такие как (0, '', false), которые могут быть действительными входами в некоторых случаях.

let x = {
  profile: {
    name: '浪里行舟',
    age: ''
  }
}
console.log(x.profile.age || 18) //18

В приведенном выше примере атрибут age представляет собой пустую строку, но считается ложным значением.Чтобы решить эту проблему, в ES2020 есть новая функция — оператор слияния с пустым пространством, который представлен символом ??. Если выражение в левой части оператора ?? оценивается какнеопределенный или нулевой, он возвращает правое значение по умолчанию.

let c = a ?? b;
// 等价于let c = a !== undefined && a !== null ? a : b;

Например, есть следующий код:

const x = null;
const y = x ?? 500;
console.log(y); // 500
const n = 0
const m = n ?? 9000;
console.log(m) // 0

Поддержка оператора объединения null:

Promise.allSettled

Мы знаем, что Promise.all может выполнять асинхронные задачи одновременно. Но его самая большая проблемаЕсли какие-либо из обещаний отклонены, все обещание. Все вызов немедленно прекратитсяи возвращает новый объект Promise, который отклоняется.

const promises = [
 Promise.resolve(1),
 Promise.resolve(2),
 Promise.reject('error')
];

Promise.all(promises)
 .then(responses => console.log(responses))
 .catch(e => console.log(e)) // "error"

Если есть такой сценарий: страница имеет три области, соответствующие трем независимым данным интерфейса, используйте Promise.all для одновременного запроса трех интерфейсов, если какой-либо из интерфейсов ненормальный, статус будет отклонен, что приведет к тому, что страница All данные в трех областях не могут быть получены, мы не можем мириться с этой ситуацией, появление Promise.allSettled может решить эту болевую точку:

Promise.allSettled([
  Promise.reject({ code: 500, msg: '服务异常' }),
  Promise.resolve({ code: 200, list: [] }),
  Promise.resolve({ code: 200, list: [] })
]).then(res => {
  console.log(res)
  /*
        0: {status: "rejected", reason: {…}}
        1: {status: "fulfilled", value: {…}}
        2: {status: "fulfilled", value: {…}}
    */
  // 过滤掉 rejected 状态,尽可能多的保证页面区域数据渲染
  RenderContent(
    res.filter(el => {
      return el.status !== 'rejected'
    })
  )
})

Promise.allSettled похож на Promise.all, его параметр принимает массив промисов, возвращает новый промис,Отличие только в том, что он не закорачивает., то есть когда все промисы обработаны, мы можем получить статус каждого промиса, независимо от того, была ли обработка успешной или нет.

Поддержка Promise.allSettled:

String.prototype.matchAll

Если регулярное выражение имеет несколько совпадений в строке, обычно используйте модификатор g или модификатор y и удаляйте их одно за другим в цикле.

function collectGroup1 (regExp, str) {
  const matches = []
  while (true) {
    const match = regExp.exec(str)
    if (match === null) break
    matches.push(match[1])
  }
  return matches
}
console.log(collectGroup1(/"([^"]*)"/g, `"foo" and "bar" and "baz"`))
// [ 'foo', 'bar', 'baz' ]

Стоит отметить, что без модификатора /g .exec() вернет только первое совпадение. Теперь с помощью метода String.prototype.matchAll можно получить все совпадения одновременно.

function collectGroup1 (regExp, str) {
  let results = []
  for (const match of str.matchAll(regExp)) {
    results.push(match[1])
  }
  return results
}
console.log(collectGroup1(/"([^"]*)"/g, `"foo" and "bar" and "baz"`))
// ["foo", "bar", "baz"]

В приведенном выше коде, поскольку string.matchAll(regex) возвращает обходчик, его можно получить с помощью цикла for...of.

Поддержка String.prototype.matchAll:

Dynamic import

Теперь, когда ресурсы внешнего интерфейса становятся все больше и больше, нет необходимости загружать все эти логические ресурсы при инициализации внешнего приложения.Чтобы отрисовать первый экран быстрее, во много раз модули динамически импортируются ( загружаются по запросу), такие как отложенная загрузка изображений и т. д. Может помочь вам повысить производительность вашего приложения.

Загрузка по требованию этих логических ресурсов обычно выполняется в обратном вызове события:

el.onclick = () => {
  import('/modules/my-module.js')
    .then(module => {
      // Do something with the module.
    })
    .catch(err => {
      // load error;
    })
}

Импорт () Может использоваться в сценариях сценариев,Функцию Import (Module) можно вызывать где угодно. Он возвращает синтаксический анализ PROMISE объекту модуля.

Это использование также поддерживает ключевое слово await.

let module = await import('/modules/my-module.js');

Динамически импортируя код, вы можете сократить время, необходимое для загрузки вашего приложения, и как можно быстрее вернуть что-либо пользователю.

Поддержка динамического импорта:

BigInt

Одна из причин, по которой javascript всегда был ужасен для математики, заключается в том, что его можно представить только безопасно.-(2^53-1)к2^53-1значение диапазона, т.е.Number.MIN_SAFE_INTEGERкNumber.MAX_SAFE_INTEGER, целочисленные вычисления или представления за пределами этого диапазона потеряют точность.

var num = Number.MAX_SAFE_INTEGER;  // -> 9007199254740991

num = num + 1; // -> 9007199254740992

// 再次加 +1 后无法正常运算
num = num + 1; // -> 9007199254740992

// 两个不同的值,却返回了true
9007199254740992 === 9007199254740993  // -> true

Так появился BigInt,Это седьмой примитивный тип, который безопасен для больших целочисленных вычислений.. Вы можете использовать те же операторы для BigInt, что и для обычных чисел, например +, -, /, *, % и т. д.

Создать значение типа BigInt также просто, как добавить n к числу. Например, 123 становится 123n. Вы также можете использовать глобальный метод BigInt(value) для преобразования, а значение входного параметра представляет собой число или числовую строку.

const aNumber = 111;
const aBigInt = BigInt(aNumber);
aBigInt === 111n // true
typeof aBigInt === 'bigint' // true
typeof 111 // "number"
typeof 111n // "bigint"

Просто добавьте n в конец числа, чтобы правильно вычислять большие числа:

1234567890123456789n * 123n;
// -> 151851850485185185047n

Однако есть одна загвоздка: в большинстве операций вы не можете смешивать BigInt с числом. Сравнивать Number и BigInt можно, но не добавлять их.

1n < 2 
// true

1n + 2
// Uncaught TypeError: Cannot mix BigInt and other types, use explicit conversions

Поддержка BigInt:

globalThis

globalThis — новый стандартный метод для получения глобального значения this . Раньше разработчики могли получить его следующими способами:

  • Окно глобальной переменной: классический способ получить глобальный объект. Но это не работает в Node.js и Web Workers.
  • Глобальная переменная self: обычно доступна только в веб-воркерах и браузерах. Но он не поддерживает Node.js. Некоторые люди определят, работает ли код в Web Workers и браузерах, оценивая, существует ли self или нет.
  • Глобальная переменная global: действует только в Node.js

Чтобы получить глобальный объект в прошлом, вы можете передать глобальную функцию:

// ES10之前的解决方案
const getGlobal = function(){
  if(typeof self !== 'undefined') return self
  if(typeof window !== 'undefined') return window
  if(typeof global !== 'undefined') return global
  throw new Error('unable to locate global object')
}

// ES10内置
globalThis.Array(0,1,2) // [0,1,2]

// 定义一个全局对象v = { value:true } ,ES10用如下方式定义
globalThis.v = { value:true }

а такжеНазначение globalThis — предоставить стандартизированный способ доступа к глобальным объектам., с помощью globalThis вы можете получить глобальный объект в любом контексте и в любое время.

Если вы используете браузер, globalThis будет окном, а если вы используете Node, globalThis будет глобальным. Поэтому больше нет необходимости рассматривать различные экологические проблемы.

// worker.js
globalThis === self
// node.js
globalThis === global
// browser.js
globalThis === window

Новое предложение также предусматривает, что Object.prototype должен находиться в цепочке прототипов глобального объекта. Следующий код уже возвращает true в последних браузерах:

Object.prototype.isPrototypeOf(globalThis); // true

Поддержка глобальногоЭто:

Добро пожаловать на официальный аккаунт: мастера фронтенда, вместе станем свидетелями вашего роста!

Справочная статья