Вы когда-нибудь задумывались, как можно перебирать свойства в объектах 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 (и, собственно, всю книгу)