В этом руководстве вы узнаете, как эффективно использовать цикл JavaScript for...in
для перебора перечисляемых свойств объекта.
Цикл for...in
используется для перечисляемых свойств, которые задаются строками объекта. Обратите внимание, что свойство может быть обозначено строкой или символом.
Свойство является перечисляемым, если для его внутреннего флага
enumerable
установлено значениеtrue
.
Флаг enumerable
по умолчанию имеет значение true
, когда свойство создается с помощью простого присваивания или с помощью инициализатора свойства:
object.propertyName = value;
или же
let obj = { propertyName: value, ... };
Синтаксис:
for(const propertyName in object) { // ... }
for...in
позволяет вам получить доступ к каждому свойству и значению объекта, не зная конкретного имени свойства. Например:
var person = { firstName: 'John', lastName: 'Doe', ssn: '299-24-2351' }; for (var prop in person) { console.log(prop + ':' + person[prop]); }
Выход:
firstName:John lastName:Doe ssn:299-24-2351
В этом примере мы использовали цикл for...in
для перебора свойств объекта человека. Мы получили доступ к значению каждого свойства, используя следующий синтаксис:
object[property];
Цикл и наследование
Когда вы перебираете свойства объекта, который наследуется от другого объекта, оператор for...in
поднимается вверх по цепочке прототипов и перечисляет унаследованные свойства. Рассмотрим следующий пример:
var decoration = { color: 'red' }; var circle = Object.create(decoration); circle.radius = 10; for (const prop in circle) { console.log(prop); }
Выход:
radius color
Объект circle
имеет свой собственный прототип, который ссылается на объект decoration
. Таким образом, цикл for...in
отображает свойства объекта circle
и его прототипа.
Если вы хотите перечислить только собственные свойства объекта, вы используете метод hasOwnProperty()
:
for (const prop in circle) { if (circle.hasOwnProperty(prop)) { console.log(prop); } }
Выход:
radius
Цикл и массив
Хорошей практикой является не использовать for...in
для перебора массива, особенно когда важен порядок элементов.
Следующий пример работает безупречно:
const items = [10, 20, 30]; let total = 0; for (const item in items) { total += items[item]; } console.log(total);
Однако, можно установить свойство встроенного типа Array
в своих библиотеках следующим образом:
Array.prototype.foo = 100;
Следовательно, for...in
не будет работать правильно:
for (var prop in items) { total += items[prop]; } console.log(total);
Выход:
220
Или другой пример:
var arr = []; // set the third element to 3, other elements are `undefined` arr[2] = 3; for (let i = 0; i & lt; arr.length; i++) { console.log(arr[i]); }
Вывод показывает три элемента массива, что правильно:
undefined undefined 3
Однако цикл for...in
игнорирует первые два элемента:
for(const key in arr) { console.log(arr[key]); }
Выход:
3
Вывод показывает только третий элемент, а не первые два элемента.
Заключение
- Цикл
for...in
перебирает перечисляемые свойства объекта. Он также поднимается до цепочки прототипов и перечисляет унаследованные свойства. - Избегайте использования цикла
for...in
для перебора элементов массива, особенно когда важен порядок индексов.