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

  • for ... in петель
  • Object.keys()
  • Object.getOwnPropertyNames()

И мы собираемся посмотреть на различия между ними, используя коз.

Итак, прежде всего, давайте создадим объект myGoat с пользовательским прототипом козла, используя Object.create, а затем давайте рассмотрим различные способы циклического перебора его свойств.

Прежде чем мы приступим к циклическому просмотру свойств myGoat, давайте немного поговорим о свойствах объекта в целом. Всем свойствам объектов назначены атрибуты, одним из которых является их значение. Вы можете просмотреть атрибуты свойства, используя метод Object.getOwnPropertyDescriptor(), или, если вы хотите просмотреть все атрибуты свойства, вы можете использовать Object.getOwnPropertyDescriptors().

Если бы мы поближе посмотрели на свойство «coat» myGoat, используя Object.getOwnPropertyDescriptor, мы бы увидели это:

Нас интересует свойство enumerable, что означает «исчисляемый». То, считается ли свойство перечисляемым, просто означает, установлено ли для этого атрибута значение true или нет. Перечисляемый атрибут свойства определяет, будет ли оно отображаться в разных типах циклов — только перечисляемые свойства будут повторяться в цикле for ... in или возвращаться из вызова функции Object.keys.

Все вновь созданные свойства объекта по умолчанию имеют перечисляемый атрибут, установленный на true. Чтобы определить неперечислимое свойство объекта, мы можем использовать Object.defineProperty, что позволяет определить все атрибуты свойства, а не только значение.

Итак, давайте добавим неперечислимое свойство в myGoat:

Теперь это наш объект myGoat:

Теперь, когда мы определили объект myGoat, давайте поговорим о тех трех методах обхода объекта, о которых я упоминал в начале статьи.

  • For ... in петель

Цикл for ... in проходит по всем перечисляемым свойствам объекта и по цепочке прототипов объекта. Если вы хотите опустить свойства прототипа, вам нужно будет отфильтровать результаты цикла с помощью hasOwnProperty, что ограничивает выполняемую операцию перечисляемыми свойствами, определенными непосредственно в объекте.

  • Object.keys

Вызов Object.keys для объекта возвращает массив, содержащий все перечисляемые ключи, непосредственно определенные для объекта, поэтому он не включает никаких свойств, определенных в цепочке прототипов. Затем их можно повторить, используя любой тип обхода массива. Те же принципы применяются для Object.values или Object.entries.

  • Object.getOwnPropertyNames

Этот метод вернет массив, содержащий все свойства, непосредственно определенные для объекта (поэтому не включая цепочку прототипов), независимо от того, являются ли они перечисляемыми или нет.

Итак, давайте посмотрим, как они выглядят при вызове на myGoat:

Заметным исключением из вышесказанного, о котором стоит упомянуть, является случай, когда объект, который вы проходите, имеет Symbol для любого из своих ключей. Символы JavaScript не появляются ни в одном из трех вышеуказанных методов; вместо этого вам придется отдельно перебирать их, используя Object.getOwnPropertySymbols.

И это все! Три разных способа просмотра свойств объекта, три немного разных набора результатов.