Объекты: перебор свойств
Материал на этой странице устарел, поэтому скрыт из оглавления сайта.
Более новая информация по этой теме находится на странице https://learn.javascript.ru/object.
Для перебора всех свойств из объекта используется цикл по свойствам for..in . Эта синтаксическая конструкция отличается от рассмотренного ранее цикла for(;;) .
for..in
for (key in obj) < /* . делать что-то с obj[key] . */ >
При этом for..in последовательно переберёт свойства объекта obj , имя каждого свойства будет записано в key и вызвано тело цикла.
Объявление переменной в цикле for (var key in obj)
Вспомогательную переменную key можно объявить прямо в цикле:
for (var key in menu) < // . >
Так иногда пишут для краткости кода. Можно использовать и любое другое название, кроме key , например for(var propName in menu) .
Пример итерации по свойствам:
var menu = < width: 300, height: 200, title: "Menu" >; for (var key in menu) < // этот код будет вызван для каждого свойства объекта // ..и выведет имя свойства и его значение alert( "Ключ: " + key + " значение: " + menu[key] ); >
Обратите внимание, мы использовали квадратные скобки menu[key] . Как уже говорилось, если имя свойства хранится в переменной, то обратиться к нему можно только так, не через точку.
Количество свойств в объекте
Как узнать, сколько свойств хранит объект?
Готового метода для этого нет.
Самый кросс-браузерный способ – это сделать цикл по свойствам и посчитать, вот так:
var menu = < width: 300, height: 200, title: "Menu" >; var counter = 0; for (var key in menu) < counter++; >alert( "Всего свойств: " + counter );
В следующих главах мы пройдём массивы и познакомимся с другим, более коротким, вызовом: Object.keys(menu).length .
В каком порядке перебираются свойства?
Для примера, рассмотрим объект, который задаёт список опций для выбора страны:
var codes = < // телефонные коды в формате "код страны": "название" "7": "Россия", "38": "Украина", // . "1": "США" >;
Здесь мы предполагаем, что большинство посетителей из России, и поэтому начинаем с 7 , это зависит от проекта.
При выборе телефонного кода мы хотели бы предлагать варианты, начиная с первого. Обычно на основе списка генерируется select , но здесь нам важно не это, а важно другое.
Правда ли, что при переборе for(key in codes) ключи key будут перечислены именно в том порядке, в котором заданы?
По стандарту – нет. Но некоторое соглашение об этом, всё же, есть.
Соглашение говорит, что если имя свойства – нечисловая строка, то такие ключи всегда перебираются в том же порядке, в каком присваивались. Так получилось по историческим причинам и изменить это сложно: поломается много готового кода.
С другой стороны, если имя свойства – число или числовая строка, то все современные браузеры сортируют такие свойства в целях внутренней оптимизации.
К примеру, рассмотрим объект с заведомо нечисловыми свойствами:
var user = < name: "Вася", surname: "Петров" >; user.age = 25; // порядок перебора соответствует порядку присвоения свойства for (var prop in user) < alert( prop ); // name, surname, age >
А теперь – что будет, если перебрать объект с кодами?
1. Введение
По умолчанию объект не является итерируемым, то есть по нему нельзя пройти циклом for или for. of как по массиву или строке. Для того, чтобы перебрать объект, существует несколько специальных конструкций. Некоторые из них чаще используются в повседневной работе, другие же необходимо знать, так как это — часть языка.
2. Цикл for. in
for (key in object) // statements >
- Перебирает ключи объекта
- Можно удалять свойства во время перебора
- Нельзя использовать для перебора массивов
const hotel = name: 'Resort Hotel', stars: 5, capacity: 100, >; // Перебор ключей объекта hotel for (const key in hotel) console.log('Key: ', key); > /* * Key: name * Key: stars * Key: capacity */
Для того чтобы получить значение свойства с таким ключом во время итерации, используется синтаксис квадратных скобок, так как ключ всегда строка.
const hotel = name: 'Resort Hotel', stars: 5, capacity: 100, >; for (const key in hotel) console.log('Value: ', hotel[key]); > /* * Value: "Resort Hotel" * Value: 5 * Value: 100 */
3. Object.keys(), Object.values(), Object.entries()
Все объекты происходят от конструктора Object . У него есть несколько очень полезных методов для работы с объектами.
- Object.keys(obj) — вернет массив, с ключами объекта obj в виде строк.
- Object.values(obj) — вернет массив, со значениями свойств объекта obj .
- Object.entries(obj) — вернет массив записей, каждым элементом которого будет еще один массив из 2-х элементов: ключа и значения этого ключа из объекта obj .
const hotel = name: 'Resort Hotel', stars: 5, capacity: 100, >; const keys = Object.keys(hotel); // ["name", "stars", "capacity"] const values = Object.values(hotel); // ["Resort Hotel", 5, 100] const entries = Object.entries(hotel); // [Array(2), Array(2), Array(2)]
Скомбинировав результат Object.keys() и цикл for. of мы можем перебрать объект. На самом деле мы перебираем массив ключей, а потом просто обращаемся к свойству объекта с таким ключом.
const hotel = name: 'Resort Hotel', stars: 5, capacity: 100, >; const keys = Object.keys(hotel); // ["name", "stars", "capacity"] for (const key of keys) console.log('Value: ', hotel[key]); > /* * Value: Resort Hotel * Value: 5 * Value: 100 */
А можно использовать результат Object.entries() , который вернет массив записей с ключами и значениями свойств объекта.
const hotel = name: 'Resort Hotel', stars: 5, capacity: 100, >; /* * Посмотрите в консоли из каких двух элементов состоит каждый подмассив. * Первый элемент это ключ свойства, второй это значение. */ const entries = Object.entries(hotel); /* * На каждой итерации по entries выберем первый элемент подмассива (ключ) * в переменную key, а второй (значение) в переменную value */ for (const entry of entries) const key = entry[0]; const value = entry[1]; console.log(`$key>: $value>`); > /* * name: Resort Hotel * stars: 5 * capacity: 100 */
Допустим перед нами стоит задача посчитать общее количество продуктов в объекте формата имя-продукта: количество . Тогда подойдет метод Object.values() для того, чтобы получить массив всех значений и потом удобно их сложить.
const goods = apples: 6, grapes: 3, bread: 4, cheese: 7, >; const values = Object.values(goods); // [6, 3, 4, 7] let total = 0; for (const value of values) total += value; > console.log(total); // 20
results matching » «
No results matching » «
Как перебрать свойства объекта в JavaScript
Различные способы переборки свойств объекта в JavaScript.
JavaScript · 08.01.2020 · читать 2 мин · Автор: Alexey Myzgin
- Цикл for in
- Object.keys
- Object.values
- Object.entries
- Object getOwnPropertyNames
Цикл for in помогает получать на каждой итерации ключ объекта, используя который, мы получаем доступ к значению объекта.
Проблема с циклом for in заключается в том, что он перебирает свойства в цепочке Prototype . Когда мы перебираем объект с помощью цикла for in , нам нужно проверить, принадлежит ли свойство этому объекту. Можно сделать это при помощи hasOwnProperty .
const obj = width: 300, height: 200, title: "Menu" > for (let key in obj) if(obj.hasOwnProperty(key)) console.log(`$key> : $obj[key]>`) > > // width : 300 // height : 200 // title : Menu
Также, есть другие способы перебрать объект, которые не требуют полагаться на for in и hasOwnProperty . Для начала нужно преобразовать объект в массив, а затем перебирать сам массив.
Мы можем преобразовать объект в массив четермя способами:
- Object.keys;
- Object.values;
- Object.entries;
- Object getOwnPropertyNames.
Метод Object.keys() принимает объект в качестве аргумента и возвращает массив с заданными ключами объекта.
Итерируя метод Object.keys с методом forEach , мы получаем доступ к паре ключ-значение объекта.
const obj = width: 300, height: 200, title: "Menu" > const keys = Object.keys(obj); // ["width", "height", "title"] keys.forEach(key => console.log(`$key> : $obj[key]>`); >); // width : 300 // height : 200 // title : Menu
Метод Object.values() принимает объект в качестве аргумента и возвращает массив с заданными значениями объекта.
Используя данный метод, мы получаем доступ только к значениям объекта.
const obj = width: 300, height: 200, title: "Menu" > const values = Object.values(obj); // [300, 200, "Menu"] values.forEach(value => console.log(value); >); // 300 // 200 // Menu
Метод Object.entries() принимает объект в качестве аргумента и возвращает массив с массивами, которые являются парами [key, value] данного объекта.
const obj = width: 300, height: 200, title: "Menu" > const entries = Object.entries(obj); // [["width", 300], ["height", 200], ["title", "Menu"]] entries.forEach(([key, value]) => console.log(`$key>: $value>`) >) // width : 300 // height : 200 // title : Menu
Так как Object.entries возвращает массив массивов, то мы деструктурируем массив в его ключ и свойство.
Метод Object.getOwnPropertyNames также принимает объект в качестве аргумента и возвращает массив строк, соответствующих перечисляемым и неперечисляемым свойствам, найденным непосредственно в объекте.
const obj = width: 300, height: 200, title: "Menu" > const getOwnPropertyNames = Object.getOwnPropertyNames(obj); // ["width", "height", "title"] getOwnPropertyNames.forEach(key => console.log(`$key> : $obj[key]>`); >) // width : 300 // height : 200 // title : Menu
Object.keys()
Метод Object.keys() возвращает массив из собственных перечисляемых свойств переданного объекта, в том же порядке, в котором они бы обходились циклом for. in (разница между циклом и методом в том, что цикл перечисляет свойства и из цепочки прототипов).
Синтаксис
Object.keys(obj)
Параметры
Объект, чьи собственные перечисляемые свойства будут возвращены.
Описание
Метод Object.keys возвращает массив строковых элементов, соответствующих именам перечисляемых свойств, найденных непосредственно в самом объекте. Порядок свойств такой же, как и при ручном перечислении свойств в объекте через цикл.
Примеры
var arr = ["a", "b", "c"]; console.log(Object.keys(arr)); // консоль: ['0', '1', '2'] // Массивоподобный объект var obj = 0: "a", 1: "b", 2: "c" >; console.log(Object.keys(obj)); // консоль: ['0', '1', '2'] // Массивоподобный объект со случайным порядком ключей var an_obj = 100: "a", 2: "b", 7: "c" >; console.log(Object.keys(an_obj)); // консоль: ['2', '7', '100'] // Свойство getFoo является не перечисляемым свойством var my_obj = Object.create( >, getFoo: value: function () return this.foo; >, >, >, ); my_obj.foo = 1; console.log(Object.keys(my_obj)); // консоль: ['foo']
Если вы хотите увидеть все свойства, а не только перечисляемые, смотрите метод Object.getOwnPropertyNames() .
Примечания
В ES5, если аргумент метода не является объектом (является примитивным значением), будет выброшено исключение TypeError . В ES2015 такой аргумент будет приведён к объекту.
> Object.keys('foo') TypeError: 'foo' is not an object // код ES5 > Object.keys('foo') ['0', '1', '2'] // код ES2015
Полифил
Для добавления поддержки совместимого метода Object.keys в старых окружениях, которые его ещё не реализуют, скопируйте следующий кусок кода:
// From https://developer.mozilla.org/ru/docs/Web/JavaScript/Reference/Global_Objects/Object/keys if (!Object.keys) Object.keys = (function () "use strict"; var hasOwnProperty = Object.prototype.hasOwnProperty, hasDontEnumBug = ! toString: null >.propertyIsEnumerable("toString"), dontEnums = [ "toString", "toLocaleString", "valueOf", "hasOwnProperty", "isPrototypeOf", "propertyIsEnumerable", "constructor", ], dontEnumsLength = dontEnums.length; return function (obj) if ( typeof obj !== "object" && (typeof obj !== "function" || obj === null) ) throw new TypeError("Object.keys called on non-object"); > var result = [], prop, i; for (prop in obj) if (hasOwnProperty.call(obj, prop)) result.push(prop); > > if (hasDontEnumBug) for (i = 0; i dontEnumsLength; i++) if (hasOwnProperty.call(obj, dontEnums[i])) result.push(dontEnums[i]); > > > return result; >; >)(); >
Пожалуйста, обратите внимание, что вышеприведённый код в IE7 (и, может быть, в IE8) включает и не перечисляемые ключи, если объект передаётся из другого окна.
Более простой полифил может быть найден в статье Javascript — Object.keys Browser Compatibility (англ.).
Спецификации
| Specification |
|---|
| ECMAScript Language Specification # sec-object.keys |
Совместимость с браузерами
BCD tables only load in the browser
Смотрите также
- Перечисляемость и собственность свойств (en-US)
- Object.prototype.propertyIsEnumerable()
- Object.create()
- Object.getOwnPropertyNames()