Объект в JavaScript, в отличие от массива, не является коллекцией. Его нельзя обходить как обычный массив с помощью цикла for..of, хотя подобная задача иногда возникает. Например, когда мы хотим распечатать все свойства на экран, или когда свойства в объект добавляются динамически — то есть их имена могут меняться в процессе жизни объекта.
В JavaScript для обхода объектов есть несколько способов. Самый простой — использовать конструкцию for..in, которая очень похожа на обычный цикл.
const course = { name: 'JS: React', slug: 'js-react' }
for (const prop in course) {
console.log(`course.${prop} = ${course[prop]}`)
}
// course.name = JS: React
// course.slug = js-react
Несмотря на простоту использования, for..in работает не совсем так, как может показаться. for..in выводит не только свойства самого объекта, но и свойства, добавленные в прототип этого объекта. Эту тему мы пока не проходили и дается она позже, но если в двух словах, то объекты в JavaScript могут быть связаны друг с другом и обращение к свойству в одном объекте может приводить к обращению (неявному) к свойству в другом объекте (прототипе). Мы уже сталкивались с таким поведением на практике, но пока обходили этот вопрос стороной.
Главное, что сейчас нужно понимать, в подавляющем большинстве случаев это нежелательное поведение. Именно поэтому for..in используется не так часто, как может показаться. Гораздо более распространенный способ — обходить ключи. Метод Object.keys(obj)
позволяет получить массив всех ключей объекта:
const course = { name: 'JS: React', slug: 'js-react' }
const keys = Object.keys(course) // [ 'name', 'slug' ]
Далее мы можем обойти в цикле массив ключей и получить нужные значения. На практике, обычно, сначала получают массив ключей и что-то с ним делают. Например, фильтруют, отбирая только нужные ключи, а затем обрабатывают исходный объект или создают новый, получая в цикле значение по ключу.
for (const key of keys) {
console.log(course[key])
}
Если ключи в процессе обхода не используются, то можно сразу получить массив значений свойств объекта. Это делает метод Object.values(obj)
:
const course = { name: 'JS: React', slug: 'js-react' }
const values = Object.values(course) // [ 'JS: React', 'js-react' ]
for (const value of values) {
console.log(value)
}
Ну, и последний вариант, метод, который возвращает сразу ключи и значения объекта. То есть каждый элемент сам будет массивом, содержащим ключ и соответствующее ему значение — [ key, value ]
. За это отвечает метод Object.entries(obj)
:
const course = { name: 'JS: React', slug: 'js-react' }
const entries = Object.entries(course)
// [[ 'name', 'JS: React' ], [ 'slug', 'js-react' ]]
Обойти такой массив циклом for...of
не составит никакого труда, а деструктуризация позволит сделать это красиво:
for (const [key, value] of entries) {
console.log(key)
console.log(value)
}
Рассмотрим пример. Реализуем функцию findKeys()
, которая возвращает список ключей объекта, значение которых равно переданному значению:
const lessonMembers = {
syntax: 3,
using: 2,
foreach: 10,
operations: 10,
destructuring: 2,
array: 2,
}
findKeys(lessonMembers, 10) // ['foreach', 'operations']
findKeys(lessonMembers, 3) // ['syntax']
Логика работы функции выглядит так:
- Обходим свойства объекта
- Если значение в свойстве совпадает с переданным, то добавляем ключ в результат
const findKeys = (obj, expectedValue) => {
const result = []
const entries = Object.entries(obj)
for (const [key, value] of entries) {
if (value === expectedValue) {
result.push(key)
}
}
return result
}
Порядок ключей
Одна из ключевых особенностей массива — наличие строгого порядка, в котором следуют элементы. В объектах это не так, порядок какой-то есть, но им нельзя управлять. Этот порядок базируется на внутренних правилах работы JavaScript. Если нам важен порядок, то для этого придется вводить дополнительный массив, в котором будет храниться список ключей в том порядке, в котором мы хотим получить вывод.
Для полного доступа к курсу нужен базовый план
Базовый план откроет полный доступ ко всем курсам, упражнениям и урокам Хекслета, проектам и пожизненный доступ к теории пройденных уроков. Подписку можно отменить в любой момент.