ECMAScript
2020 годECMAScript
Языковая спецификация номер 11. Начиная с первого издания 1997 г.ECMAScript
Он превратился в один из наиболее широко используемых языков программирования общего назначения в мире.
ES2020
(ES11) вводит следующие новые функции:
-
String
изmatchAll
метод - оператор динамического импорта
import()
import.meta
export * as ns from 'module'
Promise.allSettled
- Новый тип данных:
BigInt
GlobalThis
- Nullish coalescing Operator
- Optional Chaining
matchAll
matchAll()
Метод возвращает итератор, содержащий все результаты, соответствующие регулярному выражению. использоватьfor...of
Перейдите или используйте оператор...
Array.from
Преобразуйте его в массив.
const reg = /[0-3]/g;
const data = '2020';
console.log(data.matchAll(reg));//data.matchAll 的返回值是一个迭代器
console.log([...data.matchAll(reg)]);
/**
* 0: ["2", index: 0, input: "2020", groups: undefined]
* 1: ["0", index: 1, input: "2020", groups: undefined]
* 2: ["2", index: 2, input: "2020", groups: undefined]
* 3: ["0", index: 3, input: "2020", groups: undefined]
*/
Dynamic import
стандартное использованиеimport
Импортированные модули являются статическими, поэтому все импортированные модули будут компилироваться при их загрузке (не могут быть скомпилированы по запросу, что снижает скорость загрузки домашней страницы). В некоторых сценариях вы можете захотеть импортировать модули условно или по запросу, и в этом случае вы можете использовать динамический импорт вместо статического импорта.
существуетimport()
Раньше, когда нам нужно было условно импортировать модули, нам приходилось использоватьrequire()
.
Такие как:
if(XXX) {
const menu = require('./menu');
}
теперь можно заменить на:
if(XXX) {
const menu = import('./menu');
}
@babel/preset-env
уже включены@babel/plugin-syntax-dynamic-import
, поэтому, если вы хотите использоватьimport()
синтаксис, просто настройте@babel/preset-env
Вот и все.
намекать:Пожалуйста, не злоупотребляйте динамическим импортом (используйте только в случае необходимости). Статические фреймворки могут лучше инициализировать зависимости и лучше подходят для инструментов статического анализа иtree shaking
Играть роль.
Кроме того,import()
возвращаетpromise
объект. Например:
//menu.js
export default {
menu: 'menu'
}
//index.js
if(true) {
let menu = import('./menu');
console.log(menu); //Promise {<pending>
menu.then(data => console.log(data));//Module {default: {menu: "menu"}, __esModule: true, Symbol(Symbol.toStringTag): "Module"}
} else {
}
import.meta
import.meta
вернет объект сurl
Атрибут, возвращает URL-адрес текущего модуля, может использоваться только внутри модуля.
<script src='./main.js' type="module"></script>
//main.js
console.log(import.meta); //{url: "http://localhost:8080/main.js"} PS:使用了 http-server 启动
потому чтоimport.meta
Должен использоваться внутри модуля, если не добавленtype="module"
, консоль сообщит об ошибке:Cannot use 'import.meta' outside a module
.
Когда я впервые тестировал, я былReact
Проверено в проекте, только настроено@babel/preset-env
а также@babel/preset-react
по умолчанию, используйтеimport.meta
, будет сообщено о следующей ошибке:
Установить@open-wc/webpack-import-meta-loader
,Исправлятьwebpack
конфигурации, он может работать нормально.
module: {
rules: [
{
test: /\.js$/,
use: [
require.resolve('@open-wc/webpack-import-meta-loader'),
{
loader: 'babel-loader',
options: {
presets: [
"@babel/preset-env",
"@babel/preset-react"
]
},
}
]
}
]
}
Эффект следующий:
//src/index.js
import React from 'react';
console.log(import.meta);//{index.js:38 {url: "http://127.0.0.1:3000/src/index.js"}}
export * as ns from 'module'
Добавлен ES2020export * as XX from 'module'
,а такжеimport * as XX from 'module'
//menu.js
export * as ns from './info';
Его можно понимать как объединение следующих двух предложений в одно предложение:
import * as ns from './info';
export { ns };
Однако следует отметить, чтоexport * as ns from './info'
на самом деле не импортирует модуль, поэтому в этом модуле (menu.js
), мы не можем получитьns
из.
Promise.allSettled
Promise.all
илиPromise.race
Иногда это не соответствует нашим потребностям. Например, нам нужноpromise
Выполняйте некоторые операции, когда они закончены, и не волнуйтесь, успешны они или нет. В отсутствиеPromise.allSettled
Раньше нам нужно было писать реализацию самим.
Promise.allSettled()
метод возвращаетpromise
ужеfulfilled
илиrejected
Послеpromise
, с массивом объектов, каждый объект, представляющий соответствующуюpromise
результат.
const promise1 = Promise.resolve(100);
const promise2 = new Promise((resolve, reject) => setTimeout(reject, 100, 'info'));
const promise3 = new Promise((resolve, reject) => setTimeout(resolve, 200, 'name'))
Promise.allSettled([promise1, promise2, promise3]).
then((results) => console.log(result));
/*
[
{ status: 'fulfilled', value: 100 },
{ status: 'rejected', reason: 'info' },
{ status: 'fulfilled', value: 'name' }
]
*/
можно увидеть,Promise.allSettled()
Успешным результатом является массив, каждый элемент массива является объектом, каждый объект имеетstatus
свойство, значениеfulfilled
илиrejected
,еслиstatus
Значениеfulfilled
, то объект также имеетvalue
атрибут, значение атрибута которого соответствуетpromise
успешный результат; еслиstatus
Значениеrejected
, то объект имеетreason
атрибут, значение атрибута которого соответствуетpromise
причина отказа.
BigInt
BigInt
— это числовой тип данных, который может представлять целые числа в произвольном формате точности. До этого самое большое безопасное число в JS было 9009199254740991, то есть 2^53-1, набранное в консолиNumber.MAX_SAFE_INTEGER
смотреть. Помимо этого значения, JS не может точно представить его. Кроме того, значения больше или равные 2 в степени 1024 не могут быть представлены JS и будут возвращатьInfinity
.
BigInt
Это решает обе проблемы.BigInt
Он используется только для представления целых чисел, и нет ограничений на количество цифр.Целые числа с любым количеством цифр могут быть точно представлены. для иNumber
тип, чтобы различать,BigInt
Данные типа должны иметь суффиксn
.
//Number类型在超过9009199254740991后,计算结果即出现问题
const num1 = 90091992547409910;
console.log(num1 + 1); //90091992547409900
//BigInt 计算结果正确
const num2 = 90091992547409910n;
console.log(num2 + 1n); //90091992547409911n
//Number 类型不能表示大于 2 的 1024 次方的数值
let num3 = 9999;
for(let i = 0; i < 10; i++) {
num3 = num3 * num3;
}
console.log(num3); //Infinity
//BigInt 类型可以表示任意位数的整数
let num4 = 9999n;
for(let i = 0n; i < 10n; i++) {
num4 = num4 * num4;
}
console.log(num4); //一串超级长的数字,这里就不贴了
мы также можем использоватьBigInt
объект для инициализацииBigInt
Пример:
console.log(BigInt(999)); // 999n 注意:没有 new 关键字!!!
Следует отметить,BigInt
а такжеNumber
Это два типа данных, и их нельзя использовать напрямую для четырех арифметических операций, но их можно сравнивать.
console.log(99n == 99); //true
console.log(99n === 99); //false
console.log(99n + 1);//TypeError: Cannot mix BigInt and other types, use explicit conversionss
GlobalThis
В JS есть объект верхнего уровня, но объект верхнего уровня не является одинаковым для разных реализаций.
из разныхJavaScript
Получить глобальные объекты должны быть разные операторы в среде. существуетWeb
, пройти можноwindow
,self
Получить глобальный объект, но вWeb Workers
, Толькоself
Могу. существуетNode.js
, ни один из них недоступен и должен использоватьсяglobal
.
существуетglobalThis
Раньше мы получали глобальный объект следующим образом:
var 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');
};
ES2020
введен вglobalThis
В качестве объекта верхнего уровня в любой среде вы можете просто передатьglobalThis
Получите объект верхнего уровня.
Nullish coalescing Operator
ES2020
Добавлен оператор??
. Когда левый операндnull
илиundefined
, возвращает свой правый операнд, в противном случае возвращает левый операнд.
использовать||
оператор, когда левый операнд0
,null
,undefined
,NaN
,false
,''
, используется правый операнд. При использовании||
установить значения по умолчанию для некоторых переменных, вы можете столкнуться с непредвиденным поведением.
Например:
const defaultValue = 100;
let value = someValue || defaultValue;
//当 someValue 转成 boolean 值为 false 时,value 的值都是 defaultValue
когдаsomeValue
Когда значение равно 0, мы фактически ожидаемvalue
Значение равно 0, но ему неправильно присвоено значение 100.
??
оператор может обойти вышеуказанную проблему, он работает, только если левый операндnull
илиundefined
, возвращается правый операнд.
const defaultValue = 100;
let value = someValue ?? defaultValue;//someValue 为 0 ,value 的值是 0
Optional Chaining
необязательный оператор цепочки?.
Позволяет считывать значения свойств глубоко в цепочке связанных объектов без необходимости явно проверять, действительна ли каждая ссылка в цепочке.?.
Функция оператора аналогична.
цепной оператор, за исключением того, что когда ссылка имеет значение null (nullish
, которыйnull
илиundefined
) не вызывает ошибки, возвращаемое значение короткого замыкания этого выражения равноundefined
.
Например, мы хотим посетитьinfo
объектanimal
изreptile
изtortoise
. Но мы не увереныanimal
, reptile
существует, поэтому нам нужно написать:
const tortoise = info.animal && info.animal.reptile && info.animal.reptile.tortoise;
потому чтоnull.reptile
илиundefined.reptile
выдаст ошибку:TypeError: Cannot read property 'reptile' of undefined
илиTypeError: Cannot read property 'reptile' of null
, чтобы избежать ошибок, если свойства, к которым нам нужно получить доступ, находятся глубже, то этот код будет становиться все длиннее и длиннее.
с необязательным оператором цепочки?.
, мы в гостяхreptile
Раньше верификация больше не требоваласьinfo.animal
ценность . Так же при посещенииinfo.animal.reptile.tortoise
Раньше верификация не требоваласьinfo.animal.reptile
ценность .
Приведенный выше код упрощается до:
const tortoise = info.animal?.reptile?.tortoise;
JS пытается получить доступinfo.animal.reptile
перед этим неявно проверяется и определяетсяinfo.animal
Значение неnull
илиundefined
, если его значениеnull
илиundefined
, то вычисление выражения короткого замыкания возвращает непосредственноundefined
.
Вы можете увидеть необязательный оператор цепочки?.
Как и оператор объединения null, оба нацелены наnull
а такжеundefined
эти два значения.
Слишком далеко,ES2020
Новые возможности .