06. Object Iteration

  • Перечисляемые свойства --- это те свойства, для которых внутренний атрибут ключа выставлен в enumerable = true. Перечисляемые свойства можно перебрать в цикле for..in, за исключением полей-символов.

  • Принадлежность свойства определяется тем, принадлежит ли свойство самому объекту, или находится в его цепочке прототипов.

    • Собственные свойства принадлежат самому объекту, а

    • Унаследованные свойства принадлежат его прототипу.

В ES6 порядок перебора ключей стандартизирован:

  • Все индексы массивов, отсортированные по возрастанию. Индекс массива - специальный ключ-строка, хранящий число 0..2^32−1.

  • Все строковые ключи, в том порядке, в котором они объявлены.

  • Все символы, в том порядке в котором они объявлены.

В зависимости от способа перечисления можно получить разные свойства:

alt text

for-in

Цикл for..in перебирает перечисляемые свойства объекта в произвольном порядке, включая унаследованные:

Особенности:

  • Порядок не определен

  • Перечисляются так же и наследуемые свойства по всей цепочке прототипов.

  • Если необходимо перечислять только собственные свойства объекта, их необходимо фильтровать

  • Если свойство объекта отмечено как enumerable: false, то оно не будет встречаться в цикле.

  • В теле цикла можно изменять объект, а так же удалять его свойства.

hasOwnProperty guard

Common pattern consisting of for..in with Object.prototype.hasOwnProperty guards:

Note that in this particular case, the Object#hasOwnProperty guard is not used properly, because the lookup happens on the obj itself, which leads to potential performance issues, i.e. if you pass many different shapes of objects then the obj.hasOwnProperty access will become megamorphic, but might also turn into a correctness issue, i.e. if obj has a null prototype because obj was created via Object.create(null), then the expression obj.hasOwnProperty will raise an error. So make sure to always follow the advice to write Object.prototype.hasOwnProperty.call(obj, prop) instead, which is safe and avoids the potential negative performance impact:

for-of

Конструкция for..of в начале своего выполнения автоматически вызывает Symbol.iterator(), получает итератор и далее вызывает метод next() до получения done: true. Если функционал по перебору (метод next) предоставляется самим объектом, то можно вернуть this в качестве итератора:

Создание собственного итератора:

Object.keys(), Object.values()

Object.keys() : Array<string> --- возвращает массив имен собственных перечислимых свойств объекта.

Не возвращает унаследованные свойства

Похожие функции, работающие по тем же принципам:

  • Object.values

  • Object.entries

Object.getOwnPropertyNames()

Object.getOwnPropertyNames() : Array<string> - действует подобно функции Object.keys(), но возвращает имена всех собственных свойств указанного объекта, а не только перечислимые. Порядок свойств такой же, как при ручном переборе объекта в цикле.

Похожие методы:

  • Object.getOwnPropertySymbols(obj) : Array<symbol> -- возвращает все собственные ключи-символы объекта.

  • Reflect.ownKeys(obj) : Array<string|symbol> --- возвращает все ключи всех свойств объекта.

  • Reflect.enumerate(obj) : Iterator - возвращает все строковые значения всех перечисляемых свойств.

Last updated

Was this helpful?