Несмотря на то, что в последние семь лет я пишу на JavaScript почти каждый рабочий день, должен признаться, что уделяю мало внимания сообщениям о нововведениях от ES. Главные возможности вроде async/await и прокси — это одно, но ещё каждый год идёт поток мелких поэтапных изменений, которые не попадают в моё поле зрения, поскольку всегда находится что-то более важное для изучения.

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

ES2015


Двоичные и восьмеричные литералы


В JavaScript не часто приходится пользоваться двоичным манипулированием. Но иногда возникают задачи, которые иначе не решить. Например, когда пишешь высокопроизводительный код для слабых устройств, втискиваешь биты в локальное хранилище, выполняешь пиксельные RGB-манипуляции в браузере или работаешь с тесно упакованными двоичными форматами данных.

Всё это может потребовать большого количества работы по скрытию/объединению двоичных чисел; мне всегда казалось, что их зря упрятали в десятичные. Именно для таких случаев в ES6 добавили формат двоичных литералов: 0b.

const binaryZero = 0b0;
const binaryOne  = 0b1;
const binary255  = 0b11111111;
const binaryLong = 0b111101011101101;

Это сильно упрощает работу с двоичными флагами:

// Pizza toppings
const olives    = 0b0001;
const ham       = 0b0010;
const pineapple = 0b0100;
const artechoke = 0b1000;

const pizza_ham_pineapple = pineapple | ham;
const pizza_four_seasons  = olives | ham | artechoke;

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

Number.isNaN()


Не путать с window.isNaN(), это новый метод с гораздо более интуитивным поведением.

У классического isNaN есть несколько интересных хитростей:

isNaN(NaN)        === true
isNaN(null)       === false
isNaN(undefined)  === true
isNaN({})         === true
isNaN('0/0')      === true
isNaN('hello')    === true

Что нам это даёт? Во-первых, ни один из этих параметров на самом деле не является NaN. Как обычно, проблема во всеми «любимом» свойстве JavaScript: приведении типов. Аргументы для window.isNaN приведены к числам с помощью функции Number.

Эту проблему решает новый статический метод Number.isNaN(). Он раз и навсегда возвращает равенство аргументов, переданных ему и NaN. Это абсолютно однозначно:

Number.isNaN(NaN)       === true
Number.isNaN(null)      === false
Number.isNaN(undefined) === false
Number.isNaN({})        === false
Number.isNaN('0/0')     === false
Number.isNaN('hello')   === false

Сигнатура: Number.isNaN : (value: any) => boolean

ES2016


Оператор возведение в степень


Время от времени такое случается, так что хорошо иметь под рукой литеральный синтаксис для возведения в степень:

2**2 === 4
3**2 === 9
3**3 === 27

Странно, но я был уверен, что в JavaScript такое уже есть. Возможно, спутал с Python.

Array.prototype.includes()


Такое трудно было пропустить, но если в последние три года вы писали array.indexOf(x) !== -1, то возрадуйтесь новому методу includes:

[1, 2, 3].includes(2)    === true
[1, 2, 3].includes(true) === false

includes использует алгоритм Same Value Zero, который почти идентичен проверке на строгое равенство (===), за исключением того, что может обрабатывать значения NaN. Этот алгоритм тоже сравнивает объекты по ссылкам, а не содержимому:

const object1 = {};
const object2 = {};

const array = [object1, 78, NaN];

array.includes(object1) === true
array.includes(object2) === false
array.includes(NaN)     === true

includes может брать второй параметр, fromIndex, который позволяет вам предоставлять значение сдвига:

// positions   0  1  2  3  4
const array = [1, 1, 1, 2, 2];

array.includes(1, 2) === true
array.includes(1, 3) === false

Полезно.

Сигнатура: Array.prototype.includes : (match: any, offset?: Int) => boolean

ES2017


Разделяемые память и атомарные операции


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

Это две большие возможности с довольно сложными API, так что здесь я их описывать не буду. За подробностями отправляю вас к этой статье: https://www.sitepen.com/blog/the-return-of-sharedarraybuffers-and-atomics/. Еще не все браузеры поддерживают эти функции, но надеюсь, что в ближайшие пару лет ситуация улучшится.

ES2018


Золотая жила регулярных выражений


В ES2018 появилась целая россыпь новых возможностей регулярных выражений:

Lookbehind-сопоставления (сопоставление с предыдущими символами)


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

const regex = /(?<=\$)\d+/;
const text  = 'This cost $400';
text.match(regex) === ['400']

Всё дело в новой lookbehind-группе, близнеце lookahead-групп:

Look ahead:  (?=abc)
Look behind: (?<=abc)

Look ahead negative:  (?!abc)
Look behind negative: (?<!abc)

К сожалению, сегодня нельзя транспилировать новый lookbehind-синтаксис под старые браузеры, так что вполне возможно, какое-то время вы сможете использовать его только в Node.

Именованные группы захвата


Теперь регулярные выражения могут выбирать подвыборки и использовать для простого парсинга. До недавнего времени мы могли ссылаться на такие фрагменты только по числам, например:

const getNameParts  = /(\w+)\s+(\w+)/g;
const name          = "Weyland Smithers";
const subMatches    = getNameParts.exec(name);

subMatches[1]     === 'Weyland'
subMatches[2]     === 'Smithers'

А теперь есть синтаксис присвоения имён этим подвыборкам (или группам записи): внутри скобок в начале ставим ?<titlе>, если хотим присвоить группе имя:

const getNameParts  = /(?<first>\w+)\s(?<last>\w+)/g;
const name          = "Weyland Smithers";
const subMatches    = getNameParts.exec(name);

const {first, last} = subMatches.groups
first             === 'Weyland'
last              === 'Smithers'

К сожалению, сейчас это работает только в Chrome и Node.

Теперь точки могут отмечать новые строки


Нужно только проставлять флаг /s, например, /someRegex./s, /anotherRegex./sg.

ES2019


Array.prototype.flat() и flatMap()


Я был очень рад увидеть это в MDN.

Попросту говоря, flat() преобразует многомерный массив в одномерный на заданную максимальную глубину (depth):

const multiDimensional = [
    [1, 2, 3],
   [4, 5, 6],
   [7,[8,9]]
];

multiDimensional.flat(2) === [1, 2, 3, 4, 5, 6, 7, 8, 9]

flatMap — это map, за которым идёт flat с глубиной 1. Это полезно, если нужно мапить функцию, которая возвращает массив, но при этом вам не нужно, чтобы результат представлял собой вложенную структуру данных:

const texts = ["Hello,", "today I", "will", "use FlatMap"];

// with a plain map
const mapped = texts.map(text => text.split(' '));
mapped === ['Hello', ['today', 'I'], 'will', ['use', 'FlatMap']];

// with flatmap
const flatMapped = texts.flatMap(text => text.split(' '));
flatMapped === ['Hello', 'today', 'I', 'will', 'use', 'FlatMap'];

Неограниченные перехваты


Теперь вы можете писать выражения try/catch без привязки к киданию ошибок:

try {
 // something throws
} catch {
 // don't have to do catch(e)
}

Кстати, перехваты, в которых вы не учитываете значение e, иногда называют обработкой исключений-покемонов. Потому что вы должны поймать их все!

Методы обрезки строковых значений


Незначительно, но приятно:

const padded         = '          Hello world   ';
padded.trimStart() === 'Hello world   ';
padded.trimEnd()   === '          Hello world';

Комментарии (52)


  1. igormich88
    31.10.2019 00:02
    +2

    У меня в Chrome 78.0.3904.70

    Number.isNaN(0/0) === true
    Ну и если предположить, что
    Number.isNaN(0/0) === false 
    , то чему будет равно 0/0?


    1. qbz
      31.10.2019 00:28

      Ну, так делить на ноль вроде как нельзя, нет? Или что вас удивляет?


      1. igormich88
        31.10.2019 00:35

        В JS можно, как раз NaN и получается.


        1. qbz
          31.10.2019 01:09

          Ну, так NaN это нот-э-намбэр, то есть не валидная мат-операция, к примеру. Попробуйте пятерку разделить на "привет", то же самое будет.


          1. igormich88
            31.10.2019 01:30
            +2

            Согласен, и Number.isNaN вернёт true для 0/0 (и для 6/«привет»), а в статье написано что вернёт false.


            1. qbz
              31.10.2019 04:28

              А, ясно. Я не читал примеры, но там, судя по всему, ошибка.


            1. ScreamPassion
              31.10.2019 10:42
              +1

              Number.isNaN('0/0') === false
              Number.isNaN(0/0) === true
              В статье все правильно написано.
              Первое — вполне валидная строка (и я тоже не понимаю зачем она там для примера) и она действительно вернет false.
              Второе — мат.операция, результат которой NaN


              1. Starche
                02.11.2019 16:27
                +1

                В статье исправили, раньше было с ошибкой — просто 0/0 без кавычек.


        1. mosby
          31.10.2019 13:31
          +2

          Обращу внимание что NaN выйдет только при 0/0.
          Если делить любое другое число на 0 то получим Infinity.
          И кстати

          isNaN(Infinity) === false
          Number.isNaN(Infinity) === false
          


          1. tbl
            31.10.2019 14:24

            Ещё в копилку:

            Number.isNaN((230 - 230 / 100 * 100) / 0) === false


            1. marfenkov
              31.10.2019 17:54
              -1

              Тут дело просто в порядке операций

              Number.isNaN(((230 - 230) / 100 * 100) / 0) === true
              


          1. vanxant
            31.10.2019 14:40
            +1

            … что абсолютно соответствует принятым в матане соглашениям. 0/0 — неопределённость, 1/0 — бесконечность, и они друг другу не равны. Вот если вы попробуете сделать 2/0 — 1/0, тогда снова будет NaN


            1. lorc
              31.10.2019 15:47

              Интересный у вас матан. По определению «a» делится на «b», если существует такое «с», что a = bc.

              Рассмотрим 1 / 0. Тогда нам нужно такое «с», что 1 = 0 * c. Очевидно, его не существует. Результат умножения бесконечности на ноль не определен, потому что бесконечность — не число. Если пользоваться теорией пределов, то можно получить любое значение. Да и даже чисто умозрительно: если 1 / 0 = inf и 2 / 0 = inf, то 1 / 0 = 2 / 0 = inf. Множим на ноль и получаем что inf * 0 = 1 = 2. А если множить на ноль по другому, то получим что inf * 0 = 0 = 0.
              Но тогда непонятно почему 1 / 0 = inf, если inf * 0 = 0.

              Короче, с бесконечностями можно играться только в пределах.


              А вот ноль на ноль делиться. Действительно: 0 = 0 * с. «c» тут может быть любым. Таким образом, хоть 0 на 0 и делиться (согласно определению), но результат этого деления не определен.

              С точки зрения математики, бесконечность числом не является. А вот в IEEE 754 — является, судя по всему. Во всяком случае там +inf, -inf и NaN — разные сущности.


              1. vanxant
                31.10.2019 16:21

                Нормальный у меня матан, советский, качественный. У авторов IEEE 754 был такой же. Бесконечность — два особых числа, о их сути можно спорить (зависит от того, какие аксиомы мы выбрали в теории множеств и арифметике, которые обе заведомо неполны по Геделю). Но в любом случае для бесконечностей определены все арифметические операции с обычными числами кроме 0, а также часть операций с 0 и другой бесконечностью.
                А вот неопределённость — это не число, not-a-number. Абсолютно любая операция числа с не-числом даёт не-число.


                1. lorc
                  31.10.2019 17:00

                  Но в любом случае для бесконечностей определены все арифметические операции с обычными числами кроме 0, а также часть операций с 0 и другой бесконечностью.


                  Извините, но нет.
                  1 + inf = inf
                  2 + inf = inf
                  Такое возможно только если inf — это ноль. Но это не ноль по определению.

                  В принципе, из этого уже видно что добавление inf в множество чисел ломает групповую операцию. Т.е. с точки зрения теории групп, бесконечность никак не может входить в множество чисел. Но окей, тут действительно можно спорить о выборе аксиоматики для чисел. Давате зайдем с другой стороны.

                  То что вы описываете, называется «расширенной числовой прямой»: к обычным числам мы добавляем две неведомых зверюшки-бесконечности. И даже там деление на ноль не приводит к бесконечности:

                  When dealing with both positive and negative extended real numbers, the expression 1/0 is usually left undefined, because, although it is true that for every real nonzero sequence f that converges to 0, the reciprocal sequence 1/f is eventually contained in every neighborhood of {-inf, +inf} it is not true that the sequence 1/f must itself converge to either -inf or +inf. (wiki)


                  Короче, проблема в том, что 1 / f не сходится к +бесконечности или -бесконечности. Оно сходится и туда и туда одновременно. Собственно, поэтому в анализе и различают «просто» бесконечность, положительную и отрицательную бесконечности.

                  В том время как в IEEE 754 деление положительного числа на ноль дает положительную бесконечность, а отрицательного — отрицательную. Хотя, согласно матану, положительную бесконечность можно получить если брать односторонний предел 1 / f когда f стремиться к нулю справа. А если брать обычный предел, то как было написано выше получится «просто» бесконечность. Которой нет ни на расширенной числовой прямой, ни в IEEE 754.

                  Короче, еще раз: в обычной арифметике на ноль делить можно только сам ноль. На расширенной числовой прямой — тоже. Имеет смысл рассматривать пределы вида 1 / x, когда x->0. Но делить на ноль — все равно нельзя. Зато можно делить на бесконечность, да. И


                  1. vanxant
                    31.10.2019 18:20

                    Вы зачем-то пытаетесь приплести матан, хотя здесь просто арифметика. В ней нет пределов, разрывов производных и прочей зауми, там только числа и 4 операции.
                    И да, откуда у вас появилось требование единственности нейтрального элемента операции сложения? То, что вы знаете про моноиды, ещё не значит, что всё вокруг обязано быть моноидами.


                    1. mayorovp
                      31.10.2019 18:51
                      +1

                      А если нет никаких пределов и разрывов — то и бесконечностей быть не должно, на нормальной числовой прямой их нет.


                      1. vanxant
                        31.10.2019 19:01
                        -1

                        на нормальной числовой прямой их нет

                        Почему нет? Вы лично проверяли?:) В некоторых аксиоматиках нет, в других есть. Первые используются в школьных учебниках, вторые — на практике.


                    1. lorc
                      31.10.2019 19:41

                      Ну так просто в арифметике нет вообще никаких бесконечностей. Им там просто неоткуда взяться. И результат деления на 0 либо не существует (если делим не-ноль), либо — не определен (если делим ноль).

                      И да, откуда у вас появилось требование единственности нейтрального элемента операции сложения?

                      Вообще -то я не говорил про требование единственности нейтрального элемента. Тем более, что бесконечность им не является: а + (-а) = 0, а не inf.

                      Я сказал что добавление бесконечности ломает групповую операцию. Потому что inf + -inf не определено, например.

                      Вообще, если вы не хотите приплетать матан, то тогда вообще непонятно зачем добавлять бесконечности. Пользы то от этого никакой не будет. Ну да, можно будет сказать a / 0 = inf. А дальше что? Профит в чем? Проблемы вижу: придется в каждую теорему теории чисел добавлять фразу наподобие «кроме случаев, когда n = inf». Попробуйте докажите основную теорему арифметики, если у вас могут быть бесконечности…


                      1. vanxant
                        31.10.2019 20:07
                        -1

                        Вы ищете теоретический смысл, а он тут сугубо практический.
                        Обычная машинная арифметика — это арифметика остатков по модулю 2N. Она не очень-то подходит для обычных вычислений из-за переполнений. Скажем, складывая на 8-битном процессоре 100+100, вы получите результат -56. Мало того, что он некорректен, он выглядит нормально. Если такое произойдёт в процессе вычисления какой-то длинной формулы, вы никак не сможете понять, что результат расчёта неверен. И дальше эта ошибка поползёт по всей системе.
                        Известны тысячи багов типа «дупликации» игровых денег, предметов и т.п. как раз из-за переполнения. Но абсолютно то же самое происходит и в бухгалтерском софте, банковском, системах управления станками и самолётами и т.д. — там, где подобные штуки могут приводить — и приводят — к очень тяжёлым последствиям.
                        В IEEE 754 переполнения нет именно благодаря бесконечностям. Причем, если где-то всплыла бесконечность, вы от неё уже не избавитесь и хотя бы сразу заметите. Это не идеальный способ, но вычисления в числах с произвольной длиной до сих доступны очень не везде.


                        1. lorc
                          31.10.2019 20:49

                          Вы ищете теоретический смысл, а он тут сугубо практический.


                          Ну как бы да. Математика — теоретическая наука.

                          Напомню, все началось с того, что вы заявили что в матане 1 / 0 — это бесконечность. Я всего лишь хотел указать на вашу ошибку и предостеречь других.

                          Она не очень-то подходит для обычных вычислений из-за переполнений.


                          Зато она быстрая. А где это действительно важно — используется арифметика с насыщением. Некоторые DSP даже аппаратно ее реализуют.

                          Но абсолютно то же самое происходит и в бухгалтерском софте, банковском, системах управления станками и самолётами и т.д. — там, где подобные штуки могут приводить — и приводят — к очень тяжёлым последствиям.


                          Ну как бы есть библиотеки, которые реализуют saturating arithmetic, есть поддержка проверки переполнения со стороны компиляторов. Надо просто знать инструмент, которым пользуешься.

                          Кстати, не знаю за станки и самолеты, но финансы в принципе не используют арифметику с плавающей точкой. Только fixed point (или вообще integer, с расчетами в младших единицах валюты).

                          В IEEE 754 переполнения нет именно благодаря бесконечностям.

                          Это все безусловно хорошо. Но мы то говорили про деление на ноль?

                          Было бы правильно сказать что в IEEE 754 приняты соглашения, которые приводят к тому, что деление ненулевого числа на 0 приводит к плюс или минус бесконечности, в зависимости от знака числа и от знака нуля. А матан тут вообще не при чем.

                          И кстати, два нуля — тоже нехилое отступление от теоретической арифметики.


                          1. vanxant
                            31.10.2019 21:24

                            Математика — теоретическая наука

                            Прикладные математики мягко скажем удивлены:)
                            или вообще integer, с расчетами в младших единицах валюты

                            да, те, которые я видел изнутри, используют целые сотые доли копеек/центов (это позволяет записывать числа типа 12.34%), а десятичная точка выводится только в интерфейсе. И тоже не от хорошей жизни.
                            два нуля — тоже нехилое отступление от теоретической арифметики.

                            Это всё же лучше, чем INT_MIN (который -128 в 8-битных целых), который иногда работает как -0, а иногда как нормальное число, и для которого -(-128)=-128


                            1. mayorovp
                              31.10.2019 22:16

                              Когда это INT_MIN работает как -0?


                              1. vanxant
                                31.10.2019 22:29

                                При умножении на нечётные положительные или чётные отрицательные числа, например.


            1. mosby
              31.10.2019 16:21

              0/0 действительно неопределенность, все логично.
              А вот дальше я боюсь вы ошибаетесь.

              Вот если вы попробуете сделать 2/0 — 1/0, тогда снова будет NaN

              Что-то я вижу что любое другое число деля на 0 выходит Infinity
              1/0 === Infinity
              100/0 === Infinity
              1024/0 === Infinity
              -512/0 === -Infinity
              


              1. vanxant
                31.10.2019 16:22

                Да, но если вы возьмёте именно то что я написал (2/0 — 1/0), то будет NaN. Тут вопрос в вычитании, а не в делении. Вычитать бесконечности нельзя.


                1. mosby
                  31.10.2019 18:41

                  все. вы имели в виду вычитание бесконечности от бесконечности.
                  не правильно понял ваш коммент


  1. Devgru
    31.10.2019 00:36
    +2

    > Теперь точки могут отмечать новые строки
    > Нужно только проставлять флаг /s

    Возможно, вы имели в виду:
    Теперь точка в регулярных выражениях может захватывать переводы строк, эмодзи и некоторые другие символы, которые раньше не захватывала, если включить флаг /s.


  1. Devgru
    31.10.2019 00:38
    +2

    > Кстати, перехваты, в которых вы не учитываете значение e, иногда называют обработкой исключений-покемонов. Потому что вы должны поймать их все!

    Вот это тоже странно.

    Шутка про исключения-покемоны возникла в джаве, где можно отлавливать исключения по типу. В ES мы всегда «ловим их все», если пишем catch.


  1. 3vi1_0n3
    31.10.2019 01:58
    +1

    Читают, читают тэги, перестаньте уже


    1. bolk
      31.10.2019 10:43

      Тэги не читают, а теги — читают.


  1. Torkins
    31.10.2019 10:22

    Автору спасибо за обзор последних ES, но вот тема ES2019 не раскрыта.
    Там одни chaining (это про '.?'. Кому перечислить денег за внедрение этой фишки?..) и pipelines чего стоят!


    1. mayorovp
      31.10.2019 13:23

      Что вы имеете в виду говоря "pipelines"? Если вы про оператор |> — то он до сих пор в stage 1, и в ES2019 не сможет попасть никаким чудом.


      1. RifleR
        31.10.2019 20:34

        Строго говоря, сейчас ничего новое вообще не может попасть в ES2019, так как ES2019 уже финализирован и утвержден. Но если перейти по ссылке, то там написано, что chaining и pipelines не входят в ES2019, странно, что предыдущий комментатор этого не заметил.


  1. funny_falcon
    31.10.2019 10:41

    Хмм… `trimStart` уже есть… Осталось дождаться `leftPad`.


    1. Aquahawk
      31.10.2019 10:45

      Вы не поверите github.com/tc39/proposal-string-pad-start-end. В том что оно принято можно удостовериться тут github.com/tc39/proposals/blob/master/finished-proposals.md


    1. bolk
      31.10.2019 10:48

      const leftPad = (str, len, pad) => Array(len-str.length+1).join(pad)+str


  1. gatoazul
    31.10.2019 13:07

    Кому нужны двоичные литералы в языке, который не поддерживает целых чисел?


    1. mayorovp
      31.10.2019 13:25

      А в чём заключается противоречие?


      1. gatoazul
        31.10.2019 14:02

        Обычно такие литералы используются для битовых масок. Но для JS с его 64-битовыми float непонятно, что логические операции с этими масками в принципе делают.


        1. mayorovp
          31.10.2019 14:29
          +1

          А что непонятно-то? Результат математической операции не должен зависеть от представления операндов в памяти.


          3 | 5 будет 7 хоть в С++, хоть в Javascript


          1. tbl
            31.10.2019 14:40

            Чему будет равен "-1 | 1", а «2.3 | -1»?


            1. mayorovp
              31.10.2019 18:53

              А какая разница-то? Вы бы ещё про "foo" | 1 спросили...


              1. vanxant
                31.10.2019 19:04

                Ну вообще это (выражение a|0) — быстрый способ отбросить дробную часть числа, и, главное, подсказка для интерпретатора, что нужно перейти в целые числа. Если посмотрите asm.js, то там такого полно.


                1. mayorovp
                  31.10.2019 19:11

                  Это уже детали реализации, которые к математике отношения не имеют.


        1. yeswell
          31.10.2019 14:32

          Если числа целые (то есть если у них нет дробной части), то делают именно то, что вы ожидаете от битовых операций над беззнаковыми числами.


          1. tbl
            31.10.2019 14:49

            Хм, обнаружил, что применение битовых операций к числу в хроме приводит их к целочисленному значению. А значит можно делить целочисленно: a/b | 0, не используя Math.floor, который округляет отрицательные числа не так, как хотелось бы нематематикам.


            1. Aquahawk
              31.10.2019 14:52

              а ещё num >>> 0 и получем uint32. И полноценная арифметика на интах работает


            1. mayorovp
              31.10.2019 18:56

              Это не только в хроме, это в стандарте так. Трюк с |0 даже вошёл в asm.js как указание на целое число. Но это всё следствия динамической типизации, операция | не для этого придумывалась.


        1. Free_ze
          31.10.2019 14:51
          +2

          В JS-движках (по крайней мере в V8) есть оптимизации, которые вычленяют короткое целочисленное значение из числовых операндов при возможности и оперируют уже с ними. Рантаймовая магия, о которой юзерам языка думать не нужно.


    1. krutoo
      31.10.2019 13:31
      +1

      В свежем Chrome уже можно попробовать BigInt: typeof 2n


  1. ubogov
    02.11.2019 11:19

    Кстати есть еще Object.fromEntries, только в IE и Edge нет