JavaScript продолжает свою популярность, о чем больше не нужно упоминать

JavaScript был наиболее часто используемым языком в GitHub на протяжении многих лет, как показано на графике в отчете GitHub Octoverse. Также в недавнем опросе Stack Overflow Результаты опроса разработчиков 2019 JavaScript был назван самой популярной технологией.

В частности, ECMAScript 2015 и последующие спецификации ECMAScript, похоже, принимаются многими разработчиками без особого сопротивления.

В этой статье мы рассмотрим ключевые особенности ECMAScript 2018 и предложения, которые, как ожидается, будут включены в следующие спецификации, ECMAScript 2019 и ECMAScript 2020.

Имейте в виду:
Содержание этой статьи основано на июне 2019 года. В зависимости от времени, когда вы читаете, содержание и факты в статье могут различаться.

Некоторые изменения и новости

Хотя это не влияет напрямую на лингвистические аспекты JavaScript, произошли некоторые изменения, которые могут повлиять на косвенные аспекты, такие как среды использования и экосистемы.

Изменения в TC39

TC39, технический комитет, обсуждающий стандартные спецификации JavaScript, решил изменить свою операционную структуру с 2019 года. TC39 проводит встречи шесть раз в год, и комитет вырос до уровня, когда на собраниях приходят от 40 до 60 человек.

Структура, которая раньше была председателем и вице-председателем, сменилась на горизонтальную в виде совместной ответственности трех сопредседателей (Аки Браун (PayPal), Брайан Терлсон (Microsoft) и Юлия Старцева). »(Mozilla). В марте 2019 года он также открыл свой официальный сайт ( https://tc39.github.io ).

В статье «Год (плюс немного) на TC39», написанной Аки Брауном, сопредседателем TC39, вы можете увидеть ход встречи TC39 и ее внешний вид.

Ранее в июле 2018 года npm присоединился к ECMA International и TC39 (см. Npm присоединяется к ECMA International и TC39).

SharedArrayBuffer

Из-за уязвимостей системы безопасности Meltdown and Spectre поставщики браузеров изменили свои настройки по умолчанию, чтобы отключить использование объекта SharedArrayBuffer с 5 января 2018 года.

Эти настройки сохраняются и по сей день, за исключением Chrome. Chrome повторно активирован, начиная с версии 67, посредством изоляции сайта (см. Isue 821270: Повторное включение SharedArrayBuffer + Atomics).

Использование хрома в MS Edge

Microsoft удивила многих, объявив 6 декабря 2018 года о переходе своего браузера Microsoft Edge на работу на основе Chromium (см. Microsoft Edge: создание веб-браузера за счет расширения сотрудничества с открытым исходным кодом).

В ходе сессии вопросов и ответов с Microsoft, состоявшейся в кулуарах встречи TC39 29 января 2019 года, были выявлены следующие факты, касающиеся перехода Microsoft Edge на Chromium.

  • Нет никаких планов по использованию открытого исходного кода старого движка рендеринга.
  • Обновления существующего движка JavaScript ChakraCore будут продолжены, но не имеют долгосрочных планов.

Лимин Чжу, член команды ChakraCore, прокомментировал это так:
В настоящее время ChakraCore используется в различных проектах вне браузера. Таким образом, несмотря на изменение направления развития Microsoft Edge, наша команда продолжит поддерживать ChakraCore (см. Внедрение Chromium в Microsoft Edge и будущее ChakraCore).

Вы можете скачать Microsoft Edge на основе хрома (версия Canary / Dev / Beta) с сайта Microsoft Edge Insider Channels.

Цели и планы на будущее по преобразованию Microsoft Edge на основе Chromium можно найти в статье Microsoft Edge и Chromium с открытым исходным кодом: наше намерение.

С точки зрения разработчика, переход на Microsoft Edge может снизить нагрузку и трудности при разработке кросс-браузерных приложений.

Однако с точки зрения веб-экосистемы может произойти что-то тревожное. Потому что это сократит разнообразие браузеров.

Если вы помните время, когда Internet Explorer находился в монопольном положении, когда многие веб-сайты были ориентированы только на Internet Explorer, расширение браузеров на основе хрома было бы неприятным.

О проблемах разнообразия см. В статьях Chrome превращается в новый Internet Explorer 6 и Прощай, EdgeHTML от Mozilla.

Поддержка модуля

Поскольку поддержка модулей была добавлена ​​в ECMAScript 2015, модули теперь широко используются как важная функциональность.

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

Динамический импорт ()

Синтаксис import (), основанный на обещаниях, позволит загружать модуль динамически. Это предложение некоторое время оставалось на стадии 3, но, наконец, 6 июня достигло стадии 4 и стало частью ECMAScript 2020.

import("./myModule.mjs")  
    .then(module => {
        ...
    });
// using async/await
(async () => {
    const module = await import("./myModule.mjs");
    ...
})();

Начиная с Firefox 60, синтаксис import () можно использовать, установив флаг javascript.options.dynamicImport, и это было включено по умолчанию в Firefox 67.

Microsoft Edge (не на основе хрома) пока не поддерживает синтаксис import (), но ожидается, что он будет поддерживаться после выпуска Edge на основе хрома.

Загрузка собственного модуля

Начиная с Firefox 60, выпущенного в мае 2018 года, собственные модули (ESM) можно использовать без флага (см. Firefox 60 - Модули и другое). Node.js 8.5.0, выпущенный к сентябрю 2017 года, экспериментально поддерживает ESM.

ESM в Node.js требует флага --experimental-modules, как в примере ниже. В этом случае функция require () CommonJS будет отключена для загрузки модуля (см. Объявление новых экспериментальных модулей).

node --experimental-modules my-app.mjs

Фонд Node.js сформировал Module Team для официальной поддержки ESM. Работа команды модуля разделена на 4 фазы.

  • Этап 0
    Ответвляется от текущего узла, но удаляет большую часть реализации узла 8.5.0+ --experimental-modules.
  • Этап 1
    Добавляет «минимальное ядро» - функции, которые, по мнению рабочей группы по модулям, вероятно, появятся в любой потенциальной реализации новых ES-модулей.
  • Этап 2
    Доводит реализацию до достаточной функциональности, чтобы она могла быть полезна обычным пользователям как минимально жизнеспособный продукт.
  • Этап 3
    Повышает удобство использования и расширяет MVP.

В настоящее время работа находится в Фазе 3.

ECMAScript 2018

ECMAScript 2018 был анонсирован в июне 2018 года.

Асинхронные итераторы

Оператор async, который перечисляет данные асинхронного потока, работает аналогично типичному оператору и использует синтаксическую форму for — await — of. Разница между асинхронным оператором и обычным оператором заключается в том, что он возвращает объект Promise.

async function test() {  
    // Regular Iterator
    for (const i of list) ...
// Async Iterator
    for await (const i of asyncList) ...
}

Если вы имеете дело с асинхронными потоками вызовов, вы можете создать фабрику асинхронных операторов.

// example from: https://jakearchibald.com/2017/async-iterators-and-generators/
async function* asyncRandomNumbers() {
    const url = "https://www.random.org/integers/?num=1&min=1&max=100&col=1&base=10&format=plain&rnd=new";
while (true) {
        const response = await fetch(url);
        const text = await response.text();
        yield Number(text);
    }
}
(async function() {
    let i = 0;
for await (const number of asyncRandomNumbers()) {
        console.log(++i, "=>", number);
        if (i === 10) break;
    }
})();
// 1 "=>" 65
// 2 "=>" 62
// ...

Свойства объекта Rest / Spread

Подобно спецификации параметра Rest и оператора Spread из ECMAScript 2015, это предложение вводит назначение деструктуризации объекта и свойства распространения для литералов объекта.

// Rest property
let { x, y, ...z } = { x: 1, y: 2, a: 3, b: 4 };  
x; // 1  
y; // 2  
z; // { a: 3, b: 4 }
// Spread property
let n = { x, y, ...z };  
n; // { x: 1, y: 2, a: 3, b: 4 }

Снятие синтаксических ограничений Template Literal

Литерал шаблона снял ограничения на использование escape-последовательностей (см. Редакция литерала шаблона).

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

  • Готово: escape-последовательность интерпретируется
  • Raw: escape-последовательности - это обычный текст.
    Неинтерпретируемое значение в строке шаблона обрабатывается методом String.raw ().
function tagFunc(str, substs) {  
    return str;
}
const result = tagFunc`\u{4B}`;  
result;  // ["K"]  
result.raw; // ["\u{4B}"]

Раньше, если в шаблоне были некоторые последовательности символов после обратной косой черты, это считалось недопустимым, и необработанная строка не возвращалась.

  • \u: Юникод (например, \u004B)
  • \x: шестнадцатеричный (например, \x4B)
  • \positive: восьмеричный (например, \141)

ECMAScript 2018 устраняет все синтаксические ограничения, связанные с escape-последовательностями, и возвращает строку в необработанном виде. В этом случае интерпретируемое значение возвращает undefined.

const result = tagFunc`\131`;  
result;  // [undefined]  
result.raw; // ["\131"]

Обратитесь к разделу ES2018: Template Literal Revision для получения дополнительной информации о проблемах и решениях в шаблоне Literal.

Promise.prototype.finally

Подобно синтаксису finally оператора try...catch, это предложение вводит использование подобия для объекта Promise.

Синтаксис finally - это блок кода, который безоговорочно выполняется в конце, независимо от состояния обработки объекта Promise («разрешить» или «отклонить»). После вызова объекта Promise этот блок кода будет выполняться независимо от результата.

let isLoading = true;
fetch("https://www.random.org/integers/?num=1&min=1&max=100&col=1&base=10&format=plain&rnd=new")  
.then(function(res) {
    if(res) {
        return res.text();
    }
throw new TypeError("Error");
})
.then(function(text) { /* Success */ })
.catch(function(error) { /* Error */ })
.finally(function() {
    // will be performed regardless success or error
    isLoading = false;
});

Дополнительные сведения см. В документации MDN Promise.prototype.finally.

Регулярное выражение

Было добавлено несколько предложений по регулярным выражениям.

// previous
/./test("a");  // true
/./.test("\n");  // false
// dotAll flag
/./s.test("\n");  // true
  • Группы захвата с именем RegExp
    Предоставляет возможность присвоить имя группе захвата. The(?<name>pattern), позволит добавить <name> к шаблону группы захвата, а затем использует имя в качестве ссылки для захвата.
const rx = /(?<year>[0-9]{4})-(?<month>[0-9]{2})/;  
const match = rx.exec('2018-03');  
match.groups.year; // 2018  
match.groups.month; // 03
  • Утверждения обратного просмотра в регулярном выражении
    В регулярных выражениях за значениями определенного шаблона следует (просматривается) или не следует (отрицательный поиск) строка.
    Это предложение, контраст, дает возможность искать конкретный образец, чтобы опередить (смотреть назад) или не опередить (отрицательный взгляд назад).
// positive lookahead
/aa(?=bb)/.test("aabb"); // true
// negative lookahead
/aa(?!bb)/.test("aac");  // true
// positive lookbehind
/(?<=aa)bb/.test("aabb");  // true
// negative lookbehind
/(?<!=aa)bb/.test("bbbb");  // true
/^\p{White_Space}+$/u.test('\t \n\r');  // true /^\p{Script=Greek}+$/u.test('μετά');  // true

ECMAScript 2019

ECMAScript 2019 находится в состоянии Кандидатский проект. Судя по предыдущим датам выпуска, ожидается, что окончательный выпуск будет объявлен примерно в июне 2019 года.

Array.prototype.flat () / Array.prototype.flatMap ()

Метод Array.prototype.flat () и метод Array.prototype.flatMap () рекурсивно находят элементы подмассива на заданную глубину и создают присоединенный к нему новый массив.

// Array.prototype.flat
[1, 2, [3, 4]].flat();  // [1, 2, 3, 4]
[1, 2, [3, 4, [5, 6]]].flat(1);  // [1, 2, 3, 4, [5, 6]]
// Array.prototype.flatMap
[1, 2, 3, 4].map(x => [x * 2]);  // [[2], [4], [6], [8]]
[1, 2, 3, 4].flatMap(x => [x * 2]);  // [2, 4, 6, 8]

Краткий рассказ о наименовании. flat ():

Первоначально предложенное имя было «. flatten ()». Но MoTools (широко используемая устаревшая библиотека) уже предлагала аналогичную функциональность под тем же названием «array.prototype.flatten ()». Если имя «.flaten ()» принято как есть, вероятно, возникнут проблемы для всех тех веб-сайтов, которые используют MoTools.

Чтобы избежать конфликта, .flatten () был переименован в .flat ().
- 1) Имя '.smoosh () 'был одним из кандидатов.
- 2) Также некоторые предлагали изменить поведение MoTools' flatten (), чтобы оно работало как ECMAScript 2019 (см. Обновить Array.prototype.flaten в соответствии с предложением TC39). Но это может заставить перестать работать многие уже не обновляемые веб-сайты, как написал в Твиттере Том Дейл (который участвовал в разработке Ember и SproutCore).

Object.fromEntries ()

Object.fromEntries (), преобразует список пар ключ-значение в объект.

const entries = new Map([  
    ['foo', 'bar'],
    ['baz', 42]
]);
Object.fromEntries(entries);  // { foo: "bar", baz: 42 }

String.prototype.trimStart () / .trimEnd ()

Удаляет пробелы с начала (String.prototype.trimStart () - с псевдонимом '.trimLeft ()') или с конца (String.prototype.trimEnd () - с псевдонимом '.trimRight ()') строки .

const greeting = "   Hello world!   ";
greeting.trimStart();  // "Hello world!   "  
greeting.trimEnd();  // "   Hello world!"

Symbol.prototype.description свойство

Свойство Symbol.prototype.description возвращает необязательное доступное только для чтения описание объектов Symbol.

// will return 'Test Description'
Symbol("Test Description").description;

Необязательная привязка защелки

Предложение Необязательная привязка перехвата состоит в том, чтобы разрешить опускание параметров, если они не используются в синтаксисе перехвата в операторе try...catch.

// Traditional way
try { ··· } catch(e) { ··· }
// Optional catch binding
// if don't need the use of parameter, it can be omitted
try { ··· } catch { ··· }

Стабильность Array.prototype.sort ()

Метод Array.prototype.sort () использовал нестабильный алгоритм быстрой сортировки при сортировке массивов с более чем 10 элементами. Чтобы обеспечить правильное выравнивание массива, ECMAScript 2019 использует алгоритм Timsort для Array.prototype.short ().

Эта спецификация в настоящее время хорошо работает со всеми движками JavaScript. Однако Microsoft Edge с ChakraCore генерирует ошибку сортировки с массивом, содержащим 512+ элементов.

На приведенном ниже снимке экрана показаны результаты теста стабильности в Edge и Firefox. Как видите, Edge терпит неудачу.

Оформить более подробное обсуждение из: « Стабильность сортировки массива № ».

Правильно сформированный JSON.stringify

RFC 8259 определяет текст JSON, который должен быть закодирован в формате UTF-8 для обмена данными объекта JSON. Но когда используется JSON.stringify (), некоторые коды UTF-16 (символы от 0xD800 до 0xDFFFF, которые классифицируются как суррогат) не кодируются в UTF-8.

ECMAScript 2019 возвращает escape-последовательность вместо возврата недопустимой строки Unicode, как показано (Edge) на следующем рисунке.

Для более подробной информации ознакомьтесь с документацией по предложению.

Подложить JSON

ECMAScript утверждает, что JSON является подмножеством в JSON.parse, но это не верно, потому что строки JSON могут содержать неэкранированные символы U + 2028 LINE SEPARATOR и U + 2029 PARAGRAPH SEPARATOR.

Это предложение предполагает, что ECMA-262 может быть расширен, чтобы эти символы не нарушали JSON, чтобы быть подмножеством ECMAScript.

// if ECMA is superset of JSON, these must be true
eval('"\u2028"') === "\u2028"  // true  
eval('"\u2029"') === "\u2029"  // true

Для получения более подробной информации ознакомьтесь с документом предложения: Подложить JSON (также известный как JSON ⊂ ECMAScript)

Редакция Function.prototype.toString

Из определения в ECMAScript 2016 результат Function.prototype.toString () может отличаться в зависимости от движков. ECMAScript 2019 гарантирует возврат исходного кода в том виде, в котором он был определен (см. Версия Function.prototype.toString).

При возврате кода, определенного в функции, ECMAScript 2019 использует следующий алгоритм для возврата строки кода, определенной в функции:

  • Разрывы строк:
    \r\n (Windows) или \n (macOS) все возвращаются как \n в стиле Unix.
  • Встроенная функция:
    Все коды (в основном встроенные функции), не определенные через ECMAScript, будут возвращены как [native code].
isNaN.toString();  // "function isNaN() { [native code] }"

  • Функции, создаваемые динамически с помощью Function и GeneratorFunction:
    Механизмы должны создавать соответствующий исходный код и присоединять его к функциям.
  • Во всех остальных случаях:
    бросьте TypeError.

Подробнее о заказе: Предложение ES: версия Function.prototype.toString

ECMAScript 2020

По состоянию на 1 марта 2019 года главная ветка репо TC39 была обновлена, чтобы указывать на следующий ECMAScript 2020. (см. Журнал фиксации).

На этом этапе завершенными предложениями (этап 4) для ECMAScript 2020 являются String.prototype.matchAll () и import () , но со временем этот список будет включать больше элементов.

Метод String.prototype.matchAll () работает аналогично String.prototype.match (). Первый возвращает итератор, содержащий совпавшую строку и детали совпадения, когда он используется с флагом g(global)/y(sticky).

const str = "test1test2";  
const rx = /t(e)(st(\d?))/g;
str.match(rx);  // ["test1", "test2"]
for (const match of str.matchAll(rx)) {  
    // 1: ["test1", "e", "st1", "1", index: 0, input: "test1test2"]
    // 2: ["test2", "e", "st2", "2", index: 5, input: "test1test2"]
    match;
}

Некоторые новые или незавершенные предложения

Давайте посмотрим на некоторые интересные предложения, которые еще не были в финальной стадии.

globalThis

Обычно доступ к объекту верхнего уровня осуществляется через объект «window» в среде браузера.

По мере расширения среды выполнения способ доступа к объекту верхнего уровня также был изменен.

  • В среде Node.js доступ к объекту верхнего уровня осуществляется через объекты «global».
  • В спецификации HTML5 для этого есть «Window» и «WindowProxy», тогда как в спецификации ECMAScript 2015 оба объекта обрабатываются одинаково. доступ к объекту верхнего уровня.

Ознакомьтесь с разделом Внутреннее и внешнее окна, чтобы узнать о различиях между Window и WindowProxy объектом.

Приведенный ниже код - это простейший способ получить ссылку на объекты верхнего уровня (глобальные) независимо от среды. Но такой подход вызывает нарушение политики безопасности контента (CSP) в приложениях Chrome. (см. es6-shim ломает Chrome App CSP).

var global = Function('return this')();

Хорошо известная библиотека прокладок для совместимости с ES6, ES6 shim, использует функцию ниже для получения глобального объекта, и на данный момент это наиболее распространенный и лучший способ.

// https://github.com/paulmillr/es6-shim/blob/003ee5d15ec1b05ae2ad5ddad3c02fcf8c266e2c/es6-shim.js#L176
var getGlobal = function () {  
    /* global self, window, global */
    // the only reliable means to get the global object is
    // `Function('return this')()`
    // However, this causes CSP violations in Chrome apps.
    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');
};

Новое предложение globalThis - предоставить доступ к верхнему уровню и избавиться от дискомфорта, связанного с окружающей средой. В настоящее время находится на «этапе 3». Еще не доработан, но в Chrome 71, Firefox 65 и Node.js 12 объекты globalThis можно использовать следующим образом:

globalThis.setTimeout;  // window.setTimeout

О названии «globalThis»:

Как и в случае с Array.prototype.flat (), первое предложенное имя было глобальным. Но об использовании этого имени сообщается о взломе flickr.com, что позволило изменить имя на globalThis.

Объявления поля класса

Использование объявлений полей класса доступно, начиная с Babel 7.1.0 (выпущено 17 сентября 2018 г.). Однако это предложение еще не дошло до финальной стадии и в настоящий момент находится на «стадии 3».

Это предложение вводит декларативный синтаксис для переменных класса более интуитивно понятным и простым способом.

Инициализация
Инициализация переменной экземпляра осуществляется через конструктор.

class MyClass {  
    constructor() {
        this.x = 1;
        this.y = 2;
    }
}

С помощью поля класса переменные экземпляра могут быть определены как //Initializer часть следующего кода, а область инициализации запускается до запуска конструктора.

class MyClass {  
    // Initializer
    x = 1;
    y = 2;
    log = console.log("Initializer");
    constructor() {
        console.log("Constructor:", this.x, this.y);
    }
}
new MyClass();  
// Initializer
// Constructor: 1 2

закрытое объявление
В то время, когда JavaScript не позволял объявлять "частным", многие разработчики по соглашению использовали символ подчеркивания (‘_’) в качестве префикса. Но это было нереалистично, чтобы работать как частные (ну, есть способ на самом деле сделать переменную или метод закрытыми).

function MyClass() {  
    this._x = 1;
    this._y = 2;
}
MyClass.prototype.getX = function() {  
    return this._x;
}

Частный декларатор использует числовой символ (#) в качестве префикса, чтобы явно объявить, что это частный. Доступ к переменным или методам, начинающимся с символа «#», возможен только внутри блоков класса.

class MyClass {  
    #foo; // private field
    constructor(foo) {
        this.#foo = foo;
    }
    incFoo() {
        this.#foo++;
    }
}

Объявление и доступ
Ниже приводится простой пример объявления полей класса и доступа к ним в различных формах.

class MyClass {  
    A = 1;  // (a) instance field
    static B = 2;  // (b) static class field
    #C = 3;  // (c) private field
    getPrivate() {
        return this.#C;
    }
}
new MyClass().A;  // 1
MyClass.B;  // 2
new MyClass().getPrivate();  // 3

Более подробно см. Предложение ES: поля класса.

Встроенный модуль

Текущая спецификация встроенного модуля «Stage 1» такая же, как у ESM. Отличие от обычных ESM в том, что они «встроены» и распространяются вместе с самим браузером.

Встроенный модуль, не подвергается напрямую global. Доступно только через синтаксис импорта. Если браузер поддерживает встроенный модуль, эти модули импортируются с префиксом std: + имя модуля, как показано в следующем примере. В этом примере загружается KV Storage Module.

import {storage, StorageArea} from "std:kv-storage";

Модуль хранения KV и Предложение по импорту карт тесно связаны со спецификацией встроенного модуля. Эти два не являются частью спецификации ECMAScript и принадлежат к WICG (группе сообщества веб-инкубатора).

Модуль хранения KV
Chrome 74 добавляет первый встроенный модуль, KV Storage. KV Storage решила проблему производительности, которая была у localStorage, и унаследовала преимущества простых API.

KV Storage имеет API-интерфейсы, аналогичные объекту карты. В качестве значения ключа можно использовать строки и сериализуемые типы данных. Он возвращает итераторы Promise или Async, которые обрабатываются асинхронно.

Два названных экспорта - это «хранилище» и «StorageArea».

  • storage:
    Является экземпляром класса StorageArea с именем default (база данных хранилища по умолчанию - 'kv-storage: default ').
  • StorageArea:
    предоставляется для случаев, когда требуется дополнительная изоляция (например, сторонняя библиотека, которая хранит данные и хочет избежать конфликтов с данными, хранящимися по умолчанию storage экземпляр). Данные StorageArea хранятся в базе данных IndexedDB с именем kv-storage:${name}, где имя - это имя экземпляра StorageArea.
import {storage} from "std:kv-storage";
const main = async () => {  
  const oldPreferences = await storage.get("preferences");
  document.querySelector("form")
    .addEventListener("submit", async () => {
       const newPreferences = Object.assign({}, oldPreferences, {
         // Updated preferences go here...
       });
       await storage.set("preferences", newPreferences);
  });
};
main();

Импорт карт
Предложение Импортировать карты позволяет контролировать, какие URL-адреса выбираются import операторами и import() выражениями JavaScript, а также позволяет повторно использовать это сопоставление в контекстах, не связанных с импортом.

Карты импорта обеспечивают Polyfill и откат для встроенных модулей, позволяя им сопоставлять идентификаторы недоступных в настоящее время модулей с URL-адресами (см. Документация по проекту реализации импортированных карт v0.5).

Например, встроенный модуль KV Storage в настоящее время доступен только в Chrome. В поддерживаемом браузере вы можете загружаться без проблем, но для тех, у кого нет поддержки, вам нужно вместо этого загрузить полифил KV Storage.

В следующем примере показано, как использовать Импорт карт. Определите карту для модуля и используйте ключевое значение URL-адреса для оператора импорта.

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

<!-- The import map is inlined into your page -->  
<script type="importmap">  
{
  "imports": {
    "/path/to/kv-storage-polyfill.mjs": [
       "std:kv-storage",  // if has native support
       "/path/to/kv-storage-polyfill.mjs" // otherwise load polyfill
    ]
  }
}
</script>
<!-- Then any module scripts with import statements use the above map -->  
<script type="module">  
  import {storage} from '/path/to/kv-storage-polyfill.mjs';
// Use `storage` ...
</script>

Закрытие

JavaScript все еще претерпевает неуклонные изменения. Это доказывает, что он не случайно стал самым популярным языком в течение многих лет. Охват новых выпусков ECMAScript для браузеров и Node.js также постоянно увеличивается, и даже для некоторых предложений до его завершения.

Непрерывное развитие посредством прозрачного и надежного процесса стандартизации делает JavaScript надежным и сильным.

Давайте продолжим путь для всех !.