Object fromentries js не работает

Примеры использования некоторых новых возможностей JavaScript

Автор материала, перевод которого мы сегодня публикуем, говорит, что новые возможности JavaScript, которые попали в стандарт ES2019, уже официально доступны в браузерах Chrome, Firefox и Safari, а также на платформе Node.js. Если нужно поддерживать устаревшие браузеры, то воспользоваться новшествами можно, транспилируя JS-код с помощью Babel. Здесь мы рассмотрим примеры использования некоторых новых возможностей JS.

Метод Object.fromEntries

В ES2017 появился метод Object.entries . Он преобразует объект в массив. Например, это может выглядеть так:

Этот метод стал замечательным дополнением к возможностям языка. Дело в том, что он позволял удобно обрабатывать данные объектов с помощью многочисленных методов, встроенных в прототип Array . Среди этих методов, например, можно отметить map , filter , reduce . Но для того, чтобы преобразовать массив обратно в объект, к сожалению, удобных средств не существовало. Всё приходилось делать вручную, с помощью цикла:

Метод Object.fromEntries создан для того чтобы избавиться от подобных циклов. Он позволяет решить ту же самую задачу с помощью гораздо меньшего объёма кода. Это вполне может способствовать тому, чтобы разработчики чаще пользовались бы методами массивов для обработки преобразованных в массивы объектов.

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

▍Поддержка

Метод Array.prototype.flat

Многомерные массивы — это структуры данных, с которыми программисты встречаются довольно-таки часто. Особенно — при загрузке неких данных. При этом уменьшение размерности массива всегда было важной задачей. Решить эту задачу можно было всегда, но код её решения нельзя было назвать очень уж привлекательным.

Рассмотрим следующий пример. Здесь, в результате обработки массива объектов с помощью функции map , у нас оказывается многомерный массив. Его мы хотим сделать более «плоским».

Теперь в нашем распоряжении имеется метод Array.prototype.flat , который принимает необязательный аргумент, указывающий то, на какой уровень надо «поднять» элементы массива.

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

Оправдание подобного устройства этого метода можно найти в том, что он, по умолчанию, не стремится превратить любой массив в одномерный, требуя конкретных инструкций по преобразованию массива. Если в одномерный массив нужно преобразовать массив, точные параметры которого неизвестны, методу flat можно передать значение Infinity .

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

▍Поддержка

Метод Array.prototype.flatMap

Вместе с методом flat в нашем распоряжении теперь оказался и новый комбинированный метод — Array.prototype.flatMap . Выше мы, на самом деле, уже видели пример ситуации, в которой этот метод может пригодиться, но давайте рассмотрим ещё один пример.

Предположим, перед нами стоит задача вставки неких элементов в массив. Как мы решили бы её раньше, до появления новых возможностей JS? Например — так:

Читайте также:  Почему не работает шприц для смазки

Теперь, когда у нас есть метод Array.prototype.flat , этот код можно улучшить:

Та задача, которую мы тут решаем, основана на сравнительно популярном паттерне (особенно это касается функционального программирования). Поэтому то, как красиво мы можем её решить с помощью метода flatMap , не может не радовать:

Вспомните о том, что по умолчанию метод Array.prototype.flat работает так, будто ему передана единица. Метод flatMap ведёт себя точно так же, то есть — «поднимает» элементы массива лишь на 1 уровень. Он представляет собой результат комбинации методов map и flat .

▍Поддержка

Методы String.prototype.trimStart и String.prototype.trimEnd

Ещё одно приятное новшество ES2019 — это псевдонимы, которые дают некоторым строковым методам более понятные имена. Раньше в нашем распоряжении были методы String.prototype.trimRight и String.prototype.trimLeft :

Методы это замечательные, но хорошо то, что им дали имена, которые больше соответствуют их цели. А цель их заключается в удалении начальных и конечных пробельных символов из строк.

▍Поддержка

Необязательный аргумент блока catch

Ещё одна приятная возможность ES2019 — это то, что аргумент в блоках try-catch теперь стал необязательным. Ранее всем блокам catch надо было передавать, в качестве параметра, объект исключения. Аргумент приходилось передавать catch даже в том случае, если он не использовался.

Теперь это не так. Если объект исключения не используется в блоке catch — тогда в этот блок не нужно и ничего передавать.

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

▍Поддержка

Изменения в методе Function.prototype.toString

Стандарт ES2019 принёс изменения в то, как работает метод функций toString . Ранее он немного искажал оформление выводимого кода:

Теперь этот метод отражает реальное представление исходного кода функций.

▍Поддержка

Итоги

Здесь мы рассмотрели примеры использования лишь совсем немногих новых возможностей JavaScript. Если вы интересуетесь новшествами JS — загляните в этот репозиторий и в эту таблицу.

Уважаемые читатели! Сталкивались ли вы с ситуациями, в которых новые возможности JS заметно упрощают решение каких-нибудь задач?

Источник

Map и Set

Сейчас мы знаем о следующих сложных структурах данных:

  • Объекты для хранения именованных коллекций.
  • Массивы для хранения упорядоченных коллекций.

Но этого не всегда достаточно для решения повседневных задач. Поэтому также существуют Map и Set .

Map – это коллекция ключ/значение, как и Object . Но основное отличие в том, что Map позволяет использовать ключи любого типа.

Методы и свойства:

  • new Map() – создаёт коллекцию.
  • map.set(key, value) – записывает по ключу key значение value .
  • map.get(key) – возвращает значение по ключу или undefined , если ключ key отсутствует.
  • map.has(key) – возвращает true , если ключ key присутствует в коллекции, иначе false .
  • map.delete(key) – удаляет элемент по ключу key .
  • map.clear() – очищает коллекцию от всех элементов.
  • map.size – возвращает текущее количество элементов.

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

Map может использовать объекты в качестве ключей.

Использование объектов в качестве ключей – это одна из известных и часто применяемых возможностей объекта Map . При строковых ключах обычный объект Object может подойти, но для ключей-объектов – уже нет.

Попробуем заменить Map на Object в примере выше:

Так как visitsCountObj – это объект, то все ключи он автоматически преобразует к строке, в итоге получился строковой ключ «[object Object]» . Это не то, чего мы хотим.

Чтобы сравнивать ключи, объект Map использует алгоритм SameValueZero. Это почти такое же сравнение, что и === , с той лишь разницей, что NaN считается равным NaN . Так что NaN также может использоваться в качестве ключа.

Этот алгоритм не может быть заменён или модифицирован.

Каждый вызов map.set возвращает объект map, так что мы можем объединить вызовы в цепочку:

Читайте также:  Как настроить ac1750 wi fi range extender

Перебор Map

Для перебора коллекции Map есть 3 метода:

  • map.keys() – возвращает итерируемый объект по ключам,
  • map.values() – возвращает итерируемый объект по значениям,
  • map.entries() – возвращает итерируемый объект по парам вида [ключ, значение] , этот вариант используется по умолчанию в for..of .

В отличие от обычных объектов Object , в Map перебор происходит в том же порядке, в каком происходило добавление элементов.

Кроме этого, Map имеет встроенный метод forEach , схожий со встроенным методом массивов Array :

Object.entries: Map из Object

При создании Map мы можем указать массив (или другой итерируемый объект) с парами ключ-значение для инициализации, как здесь:

Если у нас уже есть обычный объект, и мы хотели бы создать Map из него, то поможет встроенный метод Object.entries(obj), который получает объект и возвращает массив пар ключ-значение для него, как раз в этом формате.

Так что мы можем создать Map из обычного объекта следующим образом:

Здесь Object.entries возвращает массив пар ключ-значение: [ [«name»,»John»], [«age», 30] ] . Это именно то, что нужно для создания Map .

Object.fromEntries: Object из Map

Мы только что видели, как создать Map из обычного объекта при помощи Object.entries(obj) .

Есть метод Object.fromEntries , который делает противоположное: получив массив пар вида [ключ, значение] , он создаёт из них объект:

Мы можем использовать Object.fromEntries , чтобы получить обычный объект из Map .

К примеру, у нас данные в Map , но их нужно передать в сторонний код, который ожидает обычный объект.

Вот как это сделать:

Вызов map.entries() возвращает массив пар ключ/значение, как раз в нужном формате для Object.fromEntries .

Мы могли бы написать строку (*) ещё короче:

Это то же самое, так как Object.fromEntries ожидает перебираемый объект в качестве аргумента, не обязательно массив. А перебор map как раз возвращает пары ключ/значение, так же, как и map.entries() . Так что в итоге у нас будет обычный объект с теми же ключами/значениями, что и в map .

Объект Set – это особый вид коллекции: «множество» значений (без ключей), где каждое значение может появляться только один раз.

Его основные методы это:

  • new Set(iterable) – создаёт Set , и если в качестве аргумента был предоставлен итерируемый объект (обычно это массив), то копирует его значения в новый Set .
  • set.add(value) – добавляет значение (если оно уже есть, то ничего не делает), возвращает тот же объект set .
  • set.delete(value) – удаляет значение, возвращает true , если value было в множестве на момент вызова, иначе false .
  • set.has(value) – возвращает true , если значение присутствует в множестве, иначе false .
  • set.clear() – удаляет все имеющиеся значения.
  • set.size – возвращает количество элементов в множестве.

Основная «изюминка» – это то, что при повторных вызовах set.add() с одним и тем же значением ничего не происходит, за счёт этого как раз и получается, что каждое значение появляется один раз.

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

Множество Set – как раз то, что нужно для этого:

Альтернативой множеству Set может выступать массив для хранения гостей и дополнительный код для проверки уже имеющегося элемента с помощью arr.find. Но в этом случае будет хуже производительность, потому что arr.find проходит весь массив для проверки наличия элемента. Множество Set лучше оптимизировано для добавлений, оно автоматически проверяет на уникальность.

Перебор объекта Set

Мы можем перебрать содержимое объекта set как с помощью метода for..of , так и используя forEach :

Заметим забавную вещь. Функция в forEach у Set имеет 3 аргумента: значение value , потом снова то же самое значение valueAgain , и только потом целевой объект. Это действительно так, значение появляется в списке аргументов дважды.

Читайте также:  Ublock origin как настроить

Это сделано для совместимости с объектом Map , в котором колбэк forEach имеет 3 аргумента. Выглядит немного странно, но в некоторых случаях может помочь легко заменить Map на Set и наоборот.

Set имеет те же встроенные методы, что и Map :

  • set.values() – возвращает перебираемый объект для значений,
  • set.keys() – то же самое, что и set.values() , присутствует для обратной совместимости с Map ,
  • set.entries() – возвращает перебираемый объект для пар вида [значение, значение] , присутствует для обратной совместимости с Map .

Итого

Map – коллекция пар ключ-значение.

Методы и свойства:

  • new Map([iterable]) – создаёт коллекцию, можно указать перебираемый объект (обычно массив) из пар [ключ,значение] для инициализации.
  • map.set(key, value) – записывает по ключу key значение value .
  • map.get(key) – возвращает значение по ключу или undefined , если ключ key отсутствует.
  • map.has(key) – возвращает true , если ключ key присутствует в коллекции, иначе false .
  • map.delete(key) – удаляет элемент по ключу key .
  • map.clear() – очищает коллекцию от всех элементов.
  • map.size – возвращает текущее количество элементов.

Отличия от обычного объекта Object :

  • Что угодно может быть ключом, в том числе и объекты.
  • Есть дополнительные методы, свойство size .

Set – коллекция уникальных значений, так называемое «множество».

Методы и свойства:

  • new Set([iterable]) – создаёт Set , можно указать перебираемый объект со значениями для инициализации.
  • set.add(value) – добавляет значение (если оно уже есть, то ничего не делает), возвращает тот же объект set .
  • set.delete(value) – удаляет значение, возвращает true если value было в множестве на момент вызова, иначе false .
  • set.has(value) – возвращает true , если значение присутствует в множестве, иначе false .
  • set.clear() – удаляет все имеющиеся значения.
  • set.size – возвращает количество элементов в множестве.

Перебор Map и Set всегда осуществляется в порядке добавления элементов, так что нельзя сказать, что это – неупорядоченные коллекции, но поменять порядок элементов или получить элемент напрямую по его номеру нельзя.

Источник

Object.fromEntries is not a function #799

Comments

afreix commented Sep 1, 2019

Only an issue 6.X

When I follow the instructions to create a simple aws-nodejs serverless service and run it with serverless-offline I see the below error message, when hitting a simple GET/ hello world endpoint

Commands used to create serverless service

When I run this in 5.x I don’t see any issues and my handler function returns a hello world response as expected

The text was updated successfully, but these errors were encountered:

dnalborczyk commented Sep 1, 2019

thank you for filing the issue @afreix ! that’s interesting, I’ll have a look.

dnalborczyk commented Sep 1, 2019

the issue was that the Object.fromEntries polyfill is a module with sideEffects (modifying the global namespace). the rollup build essentially changed the order of execution and the polyfilling functionality part run too late. it should be fixed now in alpha.30 .

yoannbp commented Jul 4, 2020

I had the same issue. I fixed it by updating the version of Node.js to ver. 12.x.

thetumper commented Dec 3, 2020 •

Seeing this same error:

myfunction-api | Debug: internal, implementation, error
myfunction-api | TypeError: fromEntries is not a function
myfunction-api | at parseHeaders (/var/task/node_modules/serverless-offline/dist/utils/parseHeaders.js:22:10)
myfunction-api | at LambdaProxyIntegrationEvent.create (/var/task/node_modules/serverless-offline/dist/events/http/lambda-events/LambdaProxyIntegrationEvent.js:78:45)
myfunction-api | at hapiHandler (/var/task/node_modules/serverless-offline/dist/events/http/HttpServer.js:509:45)
myfunction-api | at module.exports.internals.Manager.execute (/var/task/node_modules/@hapi/hapi/lib/toolkit.js:41:33)
myfunction-api | at Object.internals.handler (/var/task/node_modules/@hapi/hapi/lib/handler.js:46:48)
myfunction-api | at exports.execute (/var/task/node_modules/@hapi/hapi/lib/handler.js:31:36)
myfunction-api | at Request._lifecycle (/var/task/node_modules/@hapi/hapi/lib/request.js:312:68)
myfunction-api | at process._tickCallback (internal/process/next_tick.js:68:7)

Runtime is nodejs10.x.

alaycock commented Jan 13, 2021

@dnalborczyk this seems to still be a problem, as noted by the above posters, as I’m also running into this problem. Should this issue be reopened? I am running version 6.8.0, and Node 10.15.0. Node 10’s EOL is April, so I don’t think it would be inappropriate to update the required Node version to ^12.

Источник

Оцените статью