Давайте отойдем от отдельных структур данных и поговорим об итерациях над ними.
В предыдущей главе мы видели методы map.keys()
, map.values()
, map.entries()
.
Эти методы являются общими, существует общее соглашение об их использовании для структур данных. Если мы когда-нибудь создадим собственную структуру данных, нам также следует реализовать ее.
Они поддерживаются для:
Map
Set
Array
Обычные объекты также поддерживают аналогичные методы, но синтаксис немного другой.
Для простых объектов доступны следующие методы:
Object.keys(obj) – возвращает массив ключей.
Object.values(obj) – возвращает массив значений.
Object.entries(obj) – возвращает массив пар [key, value]
.
Обратите внимание на различия (например, по сравнению с картой):
Карта | Объект | |
---|---|---|
Синтаксис вызова | map.keys() | Object.keys(obj) , но не obj.keys() |
Возврат | повторяемый | «настоящий» массив |
Первое отличие состоит в том, что нам нужно вызывать Object.keys(obj)
, а не obj.keys()
.
Почему так? Основная причина – гибкость. Помните, что объекты — это основа всех сложных структур в JavaScript. Таким образом, у нас может быть собственный объект, подобный data
, который реализует собственный метод data.values()
. И мы все еще можем вызвать для него Object.values(data)
.
Второе отличие состоит в том, что методы Object.*
возвращают «настоящие» объекты массива, а не просто итерируемые объекты. Это главным образом по историческим причинам.
Например:
пусть пользователь = { имя: «Джон», возраст: 30 };
Object.keys(user) = ["name", "age"]
Object.values(user) = ["John", 30]
Object.entries(user) = [ ["name","John"], ["age",30] ]
Вот пример использования Object.values
для перебора значений свойств:
пусть пользователь = { имя: «Джон», возраст: 30 }; // цикл по значениям for (пусть значение Object.values(user)) { предупреждение (значение); // Джон, тогда 30 }
Object.keys/values/entries игнорируют символические свойства
Как и цикл for..in
, эти методы игнорируют свойства, которые используют Symbol(...)
в качестве ключей.
Обычно это удобно. Но если нам нужны еще и символические ключи, то есть отдельный метод Object.getOwnPropertySymbols, который возвращает массив только из символических ключей. Также существует метод Reflect.ownKeys(obj), который возвращает все ключи.
У объектов отсутствуют многие методы, существующие для массивов, например, map
, filter
и другие.
Если мы хотим их применить, мы можем использовать Object.entries
, а затем Object.fromEntries
:
Используйте Object.entries(obj)
, чтобы получить массив пар ключ/значение из obj
.
Используйте методы массива в этом массиве, например map
, для преобразования этих пар ключ/значение.
Используйте Object.fromEntries(array)
для полученного массива, чтобы превратить его обратно в объект.
Например, у нас есть объект с ценами, и мы хотели бы удвоить их:
пусть цены = { банан: 1, оранжевый: 2, мясо: 4, }; пусть doublePrices = Object.fromEntries( // конвертируем цены в массив, сопоставляем каждую пару ключ/значение с другой парой // и затем fromEntries возвращает объект Object.entries(цены).map(запись => [запись[0], запись[1] * 2]) ); оповещение(doublePrices.meat); // 8
На первый взгляд это может показаться сложным, но после того, как вы воспользуетесь им один или два раза, станет легко понять. Таким образом мы можем создавать мощные цепочки преобразований.
важность: 5
Существует объект salaries
с произвольным количеством зарплат.
Напишите функцию sumSalaries(salaries)
, которая возвращает сумму всех зарплат, используя Object.values
и цикл for..of
.
Если salaries
пусты, то результат должен быть 0
.
Например:
пусть зарплаты = { «Джон»: 100, «Пит»: 300, «Мария»: 250 }; alert( sumSalaries(зарплаты) ); // 650
Откройте песочницу с тестами.
функция sumSalaries(зарплаты) { пусть сумма = 0; for (пусть зарплата Object.values(salaries)) { сумма += зарплата; } сумма возврата; // 650 } пусть зарплаты = { «Джон»: 100, «Пит»: 300, «Мария»: 250 }; alert( sumSalaries(зарплаты) ); // 650
Или, опционально, мы могли бы также получить сумму, используя Object.values
, и reduce
:
// сокращаем циклы над массивом зарплат, // добавляем их // и возвращает результат функция sumSalaries(зарплаты) { return Object.values(salaries).reduce((a, b) => a + b, 0) // 650 }
Откройте решение с тестами в песочнице.
важность: 5
Напишите функцию count(obj)
, которая возвращает количество свойств объекта:
пусть пользователь = { имя: 'Джон', возраст: 30 }; Предупреждение (счетчик (пользователь)); // 2
Постарайтесь сделать код как можно короче.
PS Не обращайте внимания на символические свойства, считайте только «обычные».
Откройте песочницу с тестами.
функция счетчик (объект) { вернуть Object.keys(obj).length; }
Откройте решение с тестами в песочнице.