Вы когда-нибудь задумывались, как можно перебирать свойства в объектах JS (которые не являются массивами)? Хорошо, у меня есть.

Возможно, это не самый распространенный случай, но иногда вы сохраняете свою структуру данных как объект, а не как массив, и вам нужно перебирать все свойства структуры. В первый раз, когда это случилось со мной, я поискал в Интернете и ошибся. Помогая людям изучать JS и создавать свой код, я встречал эту ошибку много раз; поэтому я решил написать эту статью.

Разве это не просто «для… в»?

Хотя верно, что использование for … in будет перебирать свойства вашего объекта, проблема в том, что на самом деле он сделает немного больше, чем вы могли бы ожидать. Вероятно, вы стремитесь к чему-то вроде этого:

Хотя часто это может работать правильно, правда в том, что в этом подходе есть скрытые опасности. for … in будет проходить по вашему объекту, а также по его прототипам. Разве вы не знаете, что такое прототипы? Это также особенно интересно узнать о JS. Используя слова из MDN:

Прототипы - это механизм, с помощью которого объекты JavaScript наследуют функции друг от друга

Что происходит, так это то, что, если вы используете for ... in, вы также перебираете свойства цепочки прототипов вашего объекта («родительские объекты»).

Даже подумал, что это может не быть проблемой, когда вы создаете и разрабатываете свою собственную структуру данных, но это может стать намного сложнее при использовании плагинов и поддержке больших репозиториев.

Итак, представьте сценарий, в котором у вас есть объект с прототипом. Вы его откуда-то взяли. Вы можете проверить и не обязательно увидеть, что он содержит эти два свойства. Вы увидите это только тогда, когда ваш for … in выполняет итерацию по свойствам, которых вы не ожидали!

Можно увидеть, что, хотя мы никогда не определяли a, b и c для objectFromSomewhere, он владеет этим от firstObject, который на самом деле является его прототипом. Вы даже можете видеть, что сначала он прошел через d и e (свои собственные свойства), а затем перешел к свойствам прототипа. Итак, если вы используете for … in и хотите только перебирать свойства объекта, у вас проблема.

Есть способы предотвратить это, но когда вы имеете дело со сторонними библиотеками и большими базами кода, подходить к итерации с for … in будет рискованно.

Как этого избежать?

Что ж, на самом деле это просто. Есть несколько способов обойти эту проблему. Но давайте предложим вам быстрое и безопасное решение. Здесь я представляю вам Object.keys() и Object.values(). Как следует из названия, первый предоставит вам ключи объекта в виде массива (который вы сможете перебирать в любом случае). Имейте в виду, что эти методы также выполняют итерацию по функциям (это нужно проверять вручную).

Последний предоставит вам значения объекта, также в форме массива.

Для одновременного перебора ключей и значений вы также можете использовать Object.entries(), который возвращает массив, заполненный [key, value] массивами.

Просто как тот! Этим вы гарантируете контроль над своей итерацией.

Что, если я застрял на «for… in»?

По какой-либо причине, если вам нужно придерживаться for … in, вам нужно будет добавлять новую проверку в каждый цикл. Вы можете спросить объект, принадлежит ли это свойство собственному или его прототипу с помощью hasOwnProperty.

На сегодня все, ребята! Несмотря на простоту, это тот тип знаний, который избавит вас от неприятностей при разработке.

P.S .: Если вы хотите погрузиться немного глубже, я действительно рекомендую прочитать Вы не знаете JS Глава 5 (и, собственно, всю книгу)