предисловие
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
Поддержка глобальногоЭто:
Добро пожаловать на официальный аккаунт: мастера фронтенда, вместе станем свидетелями вашего роста!