Для перебора всех свойств из объекта используется цикл по свойствам 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
}
А теперь – что будет, если перебрать объект с кодами?
var codes = {
// телефонные коды в формате "код страны": "название"
"7": "Россия",
"38": "Украина",
"1": "США"
};
for (var code in codes) alert( code ); // 1, 7, 38
При запуске этого кода в современном браузере мы увидим, что на первое место попал код США!
Нарушение порядка возникло, потому что ключи численные. Интерпретатор JavaScript видит, что строка на самом деле является числом и преобразует ключ в немного другой внутренний формат. Дополнительным эффектом внутренних оптимизаций является сортировка.
А что, если мы хотим, чтобы порядок был именно таким, какой мы задали?
Это возможно. Можно применить небольшой хак, который заключается в том, чтобы сделать все ключи нечисловыми, например, добавим в начало дополнительный символ '+'
:
var codes = {
"+7": "Россия",
"+38": "Украина",
"+1": "США"
};
for (var code in codes) {
var value = codes[code];
code = +code; // ..если нам нужно именно число, преобразуем: "+7" -> 7
alert( code + ": " + value ); // 7, 38, 1 во всех браузерах
}
Итого
- Цикл по ключам:
for (key in obj)
. - Порядок перебора соответствует порядку объявления для нечисловых ключей, а числовые – сортируются (в современных браузерах).
- Если нужно, чтобы порядок перебора числовых ключей соответствовал их объявлению в объекте, то используют трюк: числовые ключи заменяют на похожие, но содержащие не только цифры. Например, добавляют в начало
+
, как описано в примере выше, а потом, в процессе обработки, преобразуют такие ключи в числа.