- for . in
- Как пишется
- Как понять
- Что такое перечисляемые свойства
- Порядок перечисления
- Изменение объекта во время перебора
- Объекты: перебор свойств
- for..in
- Количество свойств в объекте
- В каком порядке перебираются свойства?
- for. of
- Синтаксис
- Примеры
- Обход Array
- Обход String
- Обход TypedArray
- Обход Map (en-US)
- Обход Set
- Обход объекта arguments
- Обход DOM коллекций
- Закрытие итераторов
- Обход генераторов
- Не пытайтесь повторно использовать генератор
- Обход итерируемых объектов
- Различия между for. of и for. in
- Спецификации
- Совместимость с браузерами
- Смотрите также
- Found a content problem with this page?
- MDN
- Support
- Our communities
- Developers
for . in
for . . . in позволяет пройти в цикле по перечисляемым свойствам объекта, в том числе по свойствам из прототипа.
Перечисляемые свойства – это свойства, которые разработчик добавляет объекту. Встроенные свойства, например length у массива, не обходятся в цикле for . . . in .
Как пишется
Скопировать ссылку «Как пишется» Скопировано
Схематично структура для создания цикла выглядит так:
for (переменная in объект) // действия внутри цикла>
for (переменная in объект) // действия внутри цикла >
Для цикла необходимо объявить название переменной и указать сам объект, свойства которого нужно обойти. В объявленной переменной будет храниться имя свойства во время итерации:
const cat = name: 'Борис', color: 'red', age: 8> for (const key in cat) console.log(`$ – $`)>// name – 'Борис',// color – 'red',// age – 8
const cat = name: 'Борис', color: 'red', age: 8 > for (const key in cat) console.log(`$key> – $cat[key]>`) > // name – 'Борис', // color – 'red', // age – 8
Как понять
Скопировать ссылку «Как понять» Скопировано
Цикл for . . . in — это хороший способ пройти по всем свойствам объекта, но стоит помнить несколько важных особенностей.
Что такое перечисляемые свойства
Скопировать ссылку «Что такое перечисляемые свойства» Скопировано
Перечисляемые свойства объекта – это свойства, которые явно помечены такими. Сказать свойству, что оно перечисляемое, можно через специальный метод define Property ( ) . Но для простоты все свойства, которые добавляются к объекту, являются перечисляемыми по умолчанию. Встроенные свойства не перечисляется. Например, метод index Of ( ) у объекта String или метод to String ( ) у любого объекта не участвуют в цикле for . . . in .
В цикле будут перечислены не только собственные свойства объекта, но и все перечисляемые свойства из прототипа объекта и прототипа прототипа и так далее:
const a = const b = const c = Object.setPrototypeOf(b, a)Object.setPrototypeOf(c, b) for (const key in c) console.log(key)>// Выведет: c, b, a
const a = a: 1 > const b = b: 2 > const c = c: 3 > Object.setPrototypeOf(b, a) Object.setPrototypeOf(c, b) for (const key in c) console.log(key) > // Выведет: c, b, a
Порядок перечисления
Скопировать ссылку «Порядок перечисления» Скопировано
В стандарте языка нет описания того, как свойства должны перечисляться, потому порядок будет зависеть от реализации в конкретном движке браузера. Но есть базовые правила, которое можно встретить во всех браузерах:
1️⃣ Строковые имена свойств будут перечисляться в порядке их присвоения к объекту:
const developer = name: 'Ваня', language: 'JavaScript', company: 'Google'> for (const key in developer) console.log(key)>// name// language// company
const developer = name: 'Ваня', language: 'JavaScript', company: 'Google' > for (const key in developer) console.log(key) > // name // language // company
2️⃣ Числовые свойства будут перечисляться в отсортированном порядке по возрастанию:
const booksById = 341: name: 'Harry Potter' >, 144: name: 'Flowers for Algernon' >, 202: name: 'Lord of the Rings' >> for (const key in booksById) console.log(key)>// 144// 202// 341
const booksById = 341: name: 'Harry Potter' >, 144: name: 'Flowers for Algernon' >, 202: name: 'Lord of the Rings' > > for (const key in booksById) console.log(key) > // 144 // 202 // 341
Несмотря на договорённости о порядке вывода числовых ключей, не нужно использовать for . . . in для перебора массива. В будущем правила могут измениться. Для перебора у массива есть собственные методы: for Each ( ) , map ( ) и другие. В этих методах порядок перебора гарантирован.
Изменение объекта во время перебора
Скопировать ссылку «Изменение объекта во время перебора» Скопировано
Если во время выполнения for . . . in добавлять свойства в объект, то нет гарантии, что это свойство попадёт в цикл. Свойство, удалённое из объекта до того, как до него дошёл цикл, не будет участвовать в итерации.
Объекты: перебор свойств
Материал на этой странице устарел, поэтому скрыт из оглавления сайта.
Более новая информация по этой теме находится на странице https://learn.javascript.ru/object.
Для перебора всех свойств из объекта используется цикл по свойствам for..in . Эта синтаксическая конструкция отличается от рассмотренного ранее цикла for(;;) .
for..in
При этом for..in последовательно переберёт свойства объекта obj , имя каждого свойства будет записано в key и вызвано тело цикла.
Вспомогательную переменную key можно объявить прямо в цикле:
Так иногда пишут для краткости кода. Можно использовать и любое другое название, кроме key , например for(var propName in menu) .
Пример итерации по свойствам:
var menu = < width: 300, height: 200, title: "Menu" >; for (var key in menu) < // этот код будет вызван для каждого свойства объекта // ..и выведет имя свойства и его значение alert( "Ключ: " + key + " значение: " + menuJavascript обойти все свойства объекта ); >
Обратите внимание, мы использовали квадратные скобки menuJavascript обойти все свойства объекта . Как уже говорилось, если имя свойства хранится в переменной, то обратиться к нему можно только так, не через точку.
Количество свойств в объекте
Как узнать, сколько свойств хранит объект?
Готового метода для этого нет.
Самый кросс-браузерный способ – это сделать цикл по свойствам и посчитать, вот так:
var menu = < width: 300, height: 200, title: "Menu" >; var counter = 0; for (var key in menu) < counter++; >alert( "Всего свойств: " + counter );
В следующих главах мы пройдём массивы и познакомимся с другим, более коротким, вызовом: Object.keys(menu).length .
В каком порядке перебираются свойства?
Для примера, рассмотрим объект, который задаёт список опций для выбора страны:
Здесь мы предполагаем, что большинство посетителей из России, и поэтому начинаем с 7 , это зависит от проекта.
При выборе телефонного кода мы хотели бы предлагать варианты, начиная с первого. Обычно на основе списка генерируется select , но здесь нам важно не это, а важно другое.
Правда ли, что при переборе for(key in codes) ключи key будут перечислены именно в том порядке, в котором заданы?
По стандарту – нет. Но некоторое соглашение об этом, всё же, есть.
Соглашение говорит, что если имя свойства – нечисловая строка, то такие ключи всегда перебираются в том же порядке, в каком присваивались. Так получилось по историческим причинам и изменить это сложно: поломается много готового кода.
С другой стороны, если имя свойства – число или числовая строка, то все современные браузеры сортируют такие свойства в целях внутренней оптимизации.
К примеру, рассмотрим объект с заведомо нечисловыми свойствами:
var user = < name: "Вася", surname: "Петров" >; user.age = 25; // порядок перебора соответствует порядку присвоения свойства for (var prop in user) < alert( prop ); // name, surname, age >
А теперь – что будет, если перебрать объект с кодами?
for. of
Оператор for. of выполняет цикл обхода итерируемых объектов (en-US) (включая Array , Map (en-US), Set , объект аргументов (en-US) и подобных), вызывая на каждом шаге итерации операторы для каждого значения из различных свойств объекта.
Синтаксис
На каждом шаге итерации variable присваивается значение нового свойства объекта iterable . Переменная variable может быть также объявлена с помощью const , let или var .
Объект, перечисляемые свойства которого обходятся во время выполнения цикла.
Примеры
Обход Array
let iterable = [10, 20, 30]; for (let value of iterable) < value += 1; console.log(value); >// 11 // 21 // 31
Можно также использовать const вместо let , если не нужно переназначать переменные внутри блока.
let iterable = [10, 20, 30]; for (const value of iterable) < console.log(value); >// 10 // 20 // 30
Обход String
let iterable = 'boo'; for (let value of iterable) < console.log(value); >// "b" // "o" // "o"
Обход TypedArray
let iterable = new Uint8Array([0x00, 0xff]); for (let value of iterable) < console.log(value); >// 0 // 255
Обход Map (en-US)
let iterable = new Map([['a', 1], ['b', 2], ['c', 3]]); for (let entry of iterable) < console.log(entry); >// ['a', 1] // ['b', 2] // ['c', 3] for (let Javascript обойти все свойства объекта of iterable) < console.log(value); >// 1 // 2 // 3
Обход Set
let iterable = new Set([1, 1, 2, 2, 3, 3]); for (let value of iterable) < console.log(value); >// 1 // 2 // 3
Обход объекта arguments
Обход DOM коллекций
Обход DOM коллекций наподобие NodeList : следующий пример добавляет класс read параграфам, являющимся непосредственными потомками статей:
// Примечание: работает только на платформах, где // реализован NodeList.prototype[Symbol.iterator] let articleParagraphs = document.querySelectorAll(‘article > p’); for (let paragraph of articleParagraphs)
Закрытие итераторов
В циклах for. of аварийный выход осуществляется через break , throw или return . Во всех вариантах итератор завершается.
function* foo()< yield 1; yield 2; yield 3; >; for (let o of foo()) < console.log(o); break; // итератор закрывается, возврат >
Обход генераторов
Вы можете выполнять обход генераторов, вот пример:
function* fibonacci() // функция-генератор let [prev, curr] = [0, 1]; for (;;) [prev, curr] = [curr, prev + curr]; yield curr; > > for (let n of fibonacci()) // ограничивает последовательность на 1000 if (n > 1000) break; console.log(n); >
Не пытайтесь повторно использовать генератор
Генераторы нельзя использовать дважды, даже если цикл for. of завершится аварийно, например, через оператор break . При выходе из цикла генератор завершается, и любые попытки получить из него значение обречены.
var gen = (function *() yield 1; yield 2; yield 3; >)(); for (let o of gen) console.log(o); break; // Завешение обхода > // Генератор нельзя повторно обойти, следующее не имеет смысла! for (let o of gen) console.log(o); // Не будет вызван >
Обход итерируемых объектов
Кроме того, можно сделать обход объекта, явно реализующего iterable:
var iterable = < [Symbol.iterator]() < return < i: 0, next() < if (this.i < 3) < return < value: this.i++, done: false >; > return < value: undefined, done: true >; > >; > >; for (var value of iterable) < console.log(value); >// 0 // 1 // 2
Различия между for. of и for. in
Оба оператора, и for. in и for. of производят обход объектов . Разница в том, как они это делают.
Для for. in обход перечисляемых свойств объекта осуществляется в произвольном порядке.
Для for. of обход происходит в соответствии с тем, какой порядок определён в итерируемом объекте (en-US) .
Следующий пример показывает различия в работе циклов for. of и for. in при обходе Array .
Object.prototype.objCustom = function() <>; Array.prototype.arrCustom = function() <>; let iterable = [3, 5, 7]; iterable.foo = 'hello'; for (let i in iterable) < console.log(i); // выведет 0, 1, 2, "foo", "arrCustom", "objCustom" >for (let i in iterable) < if (iterable.hasOwnProperty(i)) < console.log(i); // выведет 0, 1, 2, "foo" >> for (let i of iterable) < console.log(i); // выведет 3, 5, 7 >
Разберёмся шаг за шагом в вышеописанном коде.
Object.prototype.objCustom = function() <>; Array.prototype.arrCustom = function() <>; let iterable = [3, 5, 7]; iterable.foo = 'hello';
Каждый объект унаследует метод objCustom и каждый массив Array унаследует метод arrCustom благодаря созданию их в Object.prototype (en-US) и Array.prototype . Объект iterable унаследует методы objCustom и arrCustom из-за наследования через прототип.
Цикл выводит только перечисляемые свойства объекта iterable , в порядке их создания. Он не выводит значения 3 , 5 , 7 и hello поскольку они не являются перечисляемыми, фактически они вообще не являются свойствами, они являются значениями. Выводятся же имена свойств и методов, например arrCustom и objCustom . Если вы ещё не совсем поняли, по каким свойствам осуществляется обход, вот дополнительное объяснение того, как работает array iteration and for. in .
Цикл аналогичен предыдущему, но использует hasOwnProperty() для проверки того, собственное ли это свойство объекта или унаследованное. Выводятся только собственные свойства. Имена 0 , 1 , 2 и foo принадлежат только экземпляру объекта (не унаследованы). Методы arrCustom и objCustom не выводятся, поскольку они унаследованы.
Этот цикл обходит iterable и выводит те значения итерируемого объекта, которые определены в способе его перебора, т.е. не свойства объекта, а значения массива 3 , 5 , 7 .
Спецификации
Совместимость с браузерами
BCD tables only load in the browser
Смотрите также
Found a content problem with this page?
This page was last modified on 7 нояб. 2022 г. by MDN contributors.
Your blueprint for a better internet.
MDN
Support
Our communities
Developers
Visit Mozilla Corporation’s not-for-profit parent, the Mozilla Foundation.
Portions of this content are ©1998– 2023 by individual mozilla.org contributors. Content available under a Creative Commons license.