Вы освоили все эти 9 новых функций, добавленных в ES11?

внешний интерфейс JavaScript
Вы освоили все эти 9 новых функций, добавленных в ES11?

ECMAScript2020 год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Новые возможности .

использованная литература