Зарегистрируйтесь для доступа к 15+ бесплатным курсам по программированию с тренажером

Обход свойств объекта JS: Объекты

Объект в 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']

Логика работы функции выглядит так:

  1. Обходим свойства объекта
  2. Если значение в свойстве совпадает с переданным, то добавляем ключ в результат
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;
};

https://repl.it/@hexlet/js-objects-for-of-find-keys

Порядок ключей

Одна из ключевых особенностей массива – наличие строгого порядка, в котором следуют элементы. В объектах это не так, порядок какой-то есть, но им нельзя управлять. Этот порядок базируется на внутренних правилах работы JavaScript. Если нам важен порядок, то для этого придется вводить дополнительный массив, в котором будет храниться список ключей в том порядке, в котором мы хотим получить вывод.


Аватары экспертов Хекслета

Остались вопросы? Задайте их в разделе «Обсуждение»

Вам ответят команда поддержки Хекслета или другие студенты.

Ошибки, сложный материал, вопросы >
Нашли опечатку или неточность?

Выделите текст, нажмите ctrl + enter и отправьте его нам. В течение нескольких дней мы исправим ошибку или улучшим формулировку.

Что-то не получается или материал кажется сложным?

Загляните в раздел «Обсуждение»:

  • задайте вопрос. Вы быстрее справитесь с трудностями и прокачаете навык постановки правильных вопросов, что пригодится и в учёбе, и в работе программистом;
  • расскажите о своих впечатлениях. Если курс слишком сложный, подробный отзыв поможет нам сделать его лучше;
  • изучите вопросы других учеников и ответы на них. Это база знаний, которой можно и нужно пользоваться.
Об обучении на Хекслете

Для полного доступа к курсу нужен базовый план

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

Получить доступ
900
упражнений
2000+
часов теории
3200
тестов

Открыть доступ

Курсы программирования для новичков и опытных разработчиков. Начните обучение бесплатно.

  • 120 курсов, 2000+ часов теории
  • 900 практических заданий в браузере
  • 360 000 студентов
Отправляя форму, вы соглашаетесь c «Политикой конфиденциальности» и «Условиями оказания услуг»

Наши выпускники работают в компаниях:

Логотип компании Альфа Банк
Логотип компании Aviasales
Логотип компании Yandex
Логотип компании Tinkoff
Рекомендуемые программы

С нуля до разработчика. Возвращаем деньги, если не удалось найти работу.

Иконка программы Фронтенд-разработчик
Профессия
Разработка фронтенд-компонентов веб-приложений
20 октября 8 месяцев
Иконка программы Node.js-разработчик
Профессия
Разработка бэкенд-компонентов веб-приложений
20 октября 8 месяцев

Есть вопрос или хотите участвовать в обсуждении?

Зарегистрируйтесь или войдите в свой аккаунт

Отправляя форму, вы соглашаетесь c «Политикой конфиденциальности» и «Условиями оказания услуг»