У меня есть объект JavaScript, как показано ниже:
var p = {
"p1": "value1",
"p2": "value2",
"p3": "value3"
};
Теперь я хочу , чтобы перебрать все p
элементы ( p1
, p2
, p3
...) и получить ключи и значения. Как я могу это сделать?
Я могу изменить объект JavaScript, если это необходимо. Моя конечная цель состоит в том, чтобы пройтись по нескольким парам ключ-значение, и, если возможно, я хочу избежать использования eval
.
javascript
loops
for-loop
each
Tanmoy
источник
источник
Ответы:
Вы можете использовать
for-in
цикл, как показано другими. Однако вы также должны убедиться, что ключ, который вы получаете, является фактическим свойством объекта и не берется из прототипа.Вот фрагмент:
Альтернатива for-of с Object.keys ():
Обратите внимание на использование
for-of
вместоfor-in
, если оно не используется, оно вернет undefined для именованных свойств иObject.keys()
гарантирует использование только собственных свойств объекта без целых свойств цепочки прототипов.Используя новый
Object.entries()
метод:Примечание. Этот метод изначально не поддерживается Internet Explorer. Вы можете рассмотреть возможность использования Polyfill для старых браузеров.
источник
alert(key + " -> " + JSON.stringify(p[key]));
__proto__
orprototype
. Это свойство имеет ссылку на его родительский объект. Объект автоматически наследует свойство от своего родителя. Это причина использованияhasOwnProperty
, которая означает, что мы заинтересованы в собственном свойстве объектов, а не его родительских свойств.В ECMAScript 5 вы можете комбинировать
Object.keys()
иArray.prototype.forEach()
:ECMAScript 6 добавляет
for...of
:ECMAScript 8 добавляет,
Object.entries()
что избавляет от необходимости искать каждое значение в исходном объекте:Вы можете объединить
for...of
, деструктурировать иObject.entries
:Обе
Object.keys()
иObject.entries()
итерируют свойства в том же порядке, что иfor...in
цикл, но игнорируют цепочку прототипов . Только собственные перечисляемые свойства объекта повторяются.источник
Object.forEach(obj, function (value, key) {...})
? :( Конечноobj.forEach(function...)
, будет короче и дополнителенArray.prototype.forEach
, но это может привести к тому, что объекты определят свое собственноеforEach
свойство. Я полагаю, чтоObject.keys
защита от обратного вызова изменяет ключи объекта.Object.forEach = function (obj, callback) { Object.keys(obj).forEach(function (key) { callback(obj[key], key); }); }
Object.entries(obj).map/forEach(([key, value]) => console.log(key, value))
([ключ, значение] - деструктуризация массива, чтобы получить прямой доступ к обоим элементам. И вы должны обернуть параметры в дополнительные символы.)index
ключ в JSON? Или, если требуется, я должен использовать отдельный счетчик?for...of
это стандарт ES6, а не ES2016.Вы должны использовать цикл for-in
Но будьте очень осторожны при использовании этого вида цикла, потому что это зациклит все свойства вдоль цепи прототипа .
Поэтому при использовании циклов for-in всегда используйте
hasOwnProperty
метод, чтобы определить, действительно ли текущее свойство в итерации является свойством объекта, который вы проверяете:источник
{ }
лично, потому чтоif
без них немного неясно, что является частью,if
а что нет. Но я думаю, что это просто вопрос мнения :){ }
главным образом, чтобы избежать путаницы, если позже потребуется добавить что-то вif
область видимости.Object.prototype.hasOwnProperty.call(p, prop)
Однако, это тоже не может защитить от манипуляций с Object.prototype ...Вопрос не будет полным, если мы не будем упоминать об альтернативных методах циклического перемещения по объектам
В настоящее время многие хорошо известные библиотеки JavaScript предоставляют свои собственные методы для перебора коллекций, то есть массивов , объектов и объектов , подобных массивам . Эти методы удобны в использовании и полностью совместимы с любым браузером.
Если вы работаете с jQuery , вы можете использовать
jQuery.each()
метод. Он может быть использован для бесшовной итерации по объектам и массивам:В Underscore.js вы можете найти метод
_.each()
, который выполняет итерацию по списку элементов, передавая каждый из них поочередно предоставленной функции (обратите внимание на порядок аргументов в функции iteratee !):Lo-Dash предоставляет несколько методов для перебора свойств объекта. Basic
_.forEach()
(или его псевдоним_.each()
) полезен для циклического прохождения как объектов, так и массивов, однако (!) Объекты соlength
свойством обрабатываются как массивы, и во избежание такого поведения предлагается использовать_.forIn()
и_.forOwn()
методы (они также имеютvalue
аргумент, стоящий первым):_.forIn()
выполняет итерации по собственным и наследуемым перечисляемым свойствам объекта, в то время как_.forOwn()
итерирует только по собственным свойствам объекта (в основном проверка поhasOwnProperty
функции). Для простых объектов и литералов объектов любой из этих методов будет работать нормально.Как правило, все описанные методы имеют одинаковое поведение с любыми предоставленными объектами. Кроме того, использование собственного
for..in
цикла обычно будет быстрее, чем любая абстракция, напримерjQuery.each()
, эти методы значительно проще в использовании, требуют меньше кодирования и обеспечивают лучшую обработку ошибок.источник
В ECMAScript 5 у вас есть новый подход в итерационных полях литерала -
Object.keys
Больше информации вы можете увидеть на MDN
Мой выбор ниже в качестве более быстрого решения в текущих версиях браузеров (Chrome30, IE10, FF25)
Вы можете сравнить производительность этого подхода с различными реализациями на jsperf.com :
Поддержка браузера, которую вы можете увидеть в таблице сравнения Kangax
Для старого браузера у вас есть простой и полный polyfill
UPD:
Сравнение производительности для всех наиболее популярных случаев в этом вопросе
perfjs.info
:буквенная итерация объекта
источник
Предисловие:
Здесь, в 2018 году, ваши варианты циклического просмотра свойств объекта (некоторые примеры следуют за списком):
for-in
[ MDN , spec ] - структура цикла, которая перебирает имена перечисляемых свойств объекта, включая унаследованные, имена которых являются строкамиObject.keys
[ MDN , spec ] - функция, предоставляющая массив имен собственных , перечисляемых свойств объекта, имена которых являются строками.Object.values
[ MDN , спецификация ] - функция обеспечивает массив значений объекта в собственных , перечислимых свойствах.Object.entries
[ MDN , spec ] - функция, предоставляющая массив имен и значений собственных , перечисляемых свойств объекта (каждая запись в массиве является[name, value]
массивом).Object.getOwnPropertyNames
[ MDN , spec ] - функция, предоставляющая массив имен собственных свойств объекта (даже не перечисляемых), чьи имена являются строками.Object.getOwnPropertySymbols
[ MDN , spec ] - функция, предоставляющая массив имен собственных свойств объекта (даже не перечисляемых), чьи имена являются символами.Reflect.ownKeys
[ MDN , spec ] - функция, предоставляющая массив имен собственных свойств объекта (даже не перечисляемых), независимо от того, являются ли эти имена строками или символами.Object.getPrototypeOf
[ MDN , спецификация ] и использоватьObject.getOwnPropertyNames
,Object.getOwnPropertySymbols
илиReflect.ownKeys
по каждому объекту в цепочке прототипов (например , в нижней части этого ответа).Со всеми из них , за исключением
for-in
, вы бы использовать какой - то зацикливание конструкцию на массив (for
,for-of
,forEach
и т.д.).Примеры:
for-in
:Показать фрагмент кода
Object.keys
(сfor-of
циклом, но вы можете использовать любую конструкцию цикла) :Показать фрагмент кода
Object.values
:Показать фрагмент кода
Object.entries
:Показать фрагмент кода
Object.getOwnPropertyNames
:Показать фрагмент кода
Object.getOwnPropertySymbols
:Показать фрагмент кода
Reflect.ownKeys
:Показать фрагмент кода
Все свойства , в том числе унаследованные, не перечисляемые:
Показать фрагмент кода
источник
Вы можете просто перебрать его так:
Обратите внимание, что
key
не будет принимать значение свойства, это просто значение индекса.источник
Поскольку es2015 становится все более популярным, я публикую этот ответ, который включает использование генератора и итератора для плавного перебора
[key, value]
пар. Как это возможно в других языках, например, Ruby.Хорошо, вот код:
Всю информацию о том, как вы можете сделать итератор и генератор, вы можете найти на странице разработчика Mozilla.
Надеюсь, это помогло кому-то.
РЕДАКТИРОВАТЬ:
ES2017 будет включать в себя,
Object.entries
что сделает итерации по[key, value]
парам в объектах еще проще. Теперь известно, что он будет частью стандарта в соответствии с информацией о стадии ts39 .Я думаю, что пришло время обновить мой ответ, чтобы он стал еще свежее, чем сейчас.
Вы можете найти больше информации об использовании на странице MDN.
источник
Примечание: вы можете делать это над массивами, но вы также будете перебирать
length
и другие свойства.источник
key
просто примет индексное значение, так что будет просто предупреждать 0, 1, 2 и т. Д. Вам нужно получить доступ к p [key].var p = {"p1":"q","p2":"w"}; for(key in p) { alert( key ); }
выскакивает "p1" и "p2" в оповещениях, так что в этом плохого ???После просмотра всех ответов здесь hasOwnProperty не требуется для моего собственного использования, потому что мой объект json чист; нет никакого смысла в добавлении какой-либо дополнительной обработки javascript. Это все, что я использую:
источник
Object.prototype
, то оно будет перечисленоfor..in
. Если вы уверены, что не используете никаких библиотек, которые это делают, вам не нужно звонитьhasOwnProperty
.Object.create(null)
через прототип с помощью forEach (), который должен пропустить свойства цепочки прототипов :
источник
obj = { print: 1, each: 2, word: 3 }
производитTypeError: number is not a function
. ИспользованиеforEach
для соответствия аналогичнойArray
функции может несколько снизить риск.Интересно, что люди в этих ответах затрагивали оба
Object.keys()
вопроса,for...of
но никогда не объединяли их:Вы не можете просто , потому что это не итератор, и или ТРАЕКТОРИИ некрасиво / неэффективно. Я рад, что большинство людей воздерживаются (с проверкой или без нее ), поскольку это также немного грязно, поэтому, кроме моего ответа выше, я здесь, чтобы сказать ...
for...of
Object
for...index
.forEach()
Object.keys()
for...in
.hasOwnProperty()
Вы можете сделать обычные объектные ассоциации итерацией! Вела себя так же, как
Map
s с непосредственным использованием модногоfor...of
DEMO, работающего в Chrome и FF (я предполагаю, что только ES6)
Пока вы включите мою прокладку ниже:
Без необходимости создавать настоящий объект Map, который не имеет приятного синтаксического сахара.
На самом деле, с помощью этой прокладки, если вы все еще хотели воспользоваться преимуществами других функций Map (не добавляя их всех), но все же хотели использовать аккуратную нотацию объектов, поскольку объекты теперь итерируемы, теперь вы можете просто создать Map из нее!
Для тех, кто не любит шимить или
prototype
вообще возиться , не стесняйтесь вместо этого делать функцию в окне, вызывая ее как-getObjIterator()
то так;Теперь вы можете просто вызывать ее как обычную функцию, больше ничего не влияет
или
Нет причин, почему бы это не сработало.
Добро пожаловать в будущее.
источник
For those who don't like to shim, or mess with prototype in general, feel free to make the function on window instead, calling it something like getObjIterator() then;
ordinaryObject
для акцентирования, что магия все еще работает для этих типов). Вы проверили демоверсии? что не работает для тебя, @ noɥʇʎԀʎzɐɹƆ? (PS Ваше изображение профиля SE - босс)Таким образом, он дает тот же список ключей, что и вы, проверяя каждый ключ объекта с помощью hasOwnProperty. Вам не нужна эта дополнительная тестовая операция,
Object.keys( obj ).forEach(function( key ){})
которая должна быть быстрее. Давайте докажем это:В моем Firefox у меня есть следующие результаты
PS. на Chrome разница еще больше http://codepen.io/dsheiko/pen/JdrqXa
PS2: в ES6 (EcmaScript 2015) вы можете итерировать итерируемый объект лучше:
источник
of
не создаваяMap
sВот еще один метод, чтобы перебрать объект.
источник
for
метод может быть более производительным.источник
Вы также можете использовать Object.keys () и перебирать ключи объекта, как показано ниже, чтобы получить значение:
источник
Только код JavaScript без зависимостей:
источник
Object.keys()
Метод возвращает массив собственных перечислимых свойств заданного объекта. Подробнее об этом читайте здесьисточник
Представление
Сегодня 2020.03.06 я выполняю тесты выбранных решений на Chrome v80.0, Safari v13.0.5 и Firefox 73.0.1 на MacOs High Sierra v10.13.6
Выводы
for-in
(A, B) являются быстрыми (или самыми быстрыми) для всех браузеров для больших и маленьких объектов.for-of
(H) решение быстро на хром для маленьких и больших объектовi
(J, K), достаточно быстры во всех браузерах для небольших объектов (для Firefox также быстры для больших объектов, но средние в других браузерах)подробности
Тесты производительности были выполнены для
Ниже приведены примеры использованных решений.
Показать фрагмент кода
И вот результат для небольших объектов на хром
источник
Вы можете добавить простую функцию forEach ко всем объектам, чтобы вы могли автоматически перебирать любой объект:
Для тех людей, которые не любят метод " для ... в ":
Теперь вы можете просто позвонить:
Если вы не хотите конфликтовать с другими методами forEach, вы можете назвать его своим уникальным именем.
источник
Object
), как правило, считается анти-паттерном, потому что это может легко вызвать конфликты с другим кодом. Поэтому рану не рекомендую делать так.Циклы могут быть довольно интересными при использовании чистого JavaScript. Похоже, что только ECMA6 (новая спецификация JavaScript 2015) получила контроль над циклами. К сожалению, пока я пишу это, браузеры и популярная интегрированная среда разработки (IDE) все еще пытаются полностью поддержать новые навороты.
Вот как выглядит цикл JavaScript-объектов до ECMA6:
Кроме того, я знаю, что этот вопрос выходит за рамки этого вопроса, но в 2011 году ECMAScript 5.1 добавил
forEach
метод только для массивов, который в основном создал новый улучшенный способ циклически проходить по массивам, оставляя при этом не повторяемые объекты со старым многословным и запутаннымfor
циклом. Но странным является то, что этот новыйforEach
метод не поддерживает,break
что привело к разного рода другим проблемам.По сути, в 2011 году не было реального надежного способа зацикливания в JavaScript, кроме того, что многие популярные библиотеки (jQuery, Underscore и т. Д.) Решили повторно реализовать.
С 2015 года у нас теперь есть лучший способ зацикливания (и прерывания) любого типа объекта (включая массивы и строки). Вот как будет выглядеть цикл в JavaScript, когда рекомендация станет основной:
Обратите внимание, что большинство браузеров не поддерживают приведенный выше код по состоянию на 18 июня 2016 года. Даже в Chrome необходимо включить этот специальный флаг, чтобы он работал:
chrome://flags/#enable-javascript-harmony
До тех пор, пока это не станет новым стандартом, старый метод все еще может использоваться, но в популярных библиотеках есть альтернативы или даже облегченные альтернативы для тех, кто не использует ни одну из этих библиотек.
источник
Uncaught TypeError: Object.entries is not a function
. Разве это не реализовано в Chrome еще?В ES6 у нас есть хорошо известные символы для представления некоторых ранее внутренних методов, вы можете использовать их для определения работы итераторов для этого объекта:
это даст тот же результат, что и использование for ... в цикле es6.
Но важно знать, какие возможности у вас сейчас есть, используя es6!
источник
Object.keys()
и выделяется в памяти ... Круто!Я хотел бы сделать это, а не проверять
obj.hasOwnerProperty
в каждомfor ... in
цикле.источник
источник
json = [{"key1":"value1","key2":"value2"},{"key1":"value3","key2":"value4"}] for (var i = 0; i < json.length; i++) { for (var key in json[i]) { if (json[i].hasOwnProperty(key)) { console.log(key + " -> " + json[i][key]); } } }
Используя
for-of
наObject.keys()
Подобно:
источник
Если вы хотите перебрать и неперечислимые свойства , вы можете использовать
Object.getOwnPropertyNames(obj)
для возврата массив всех свойств (перечислимых или нет), найденных непосредственно в данном объекте.источник
Error
объект и я не мог получить свойства в цикле или_.forIn(err)
вызове. ИспользованиеObject.getOwnPropertyNames(err)
позволило мне получить доступ ко всем частям,Error
которые я не мог получить раньше. Спасибо!Если кому-то нужно перебрать arrayObjects с условием :
источник
Что касается ES6, я бы хотел добавить свою собственную ложку сахара и предоставить еще один подход для перебора свойств объекта.
Поскольку простой JS-объект не может быть повторен просто из коробки, мы не можем использовать
for..of
цикл для перебора его содержимого. Но никто не может остановить нас, чтобы сделать его итеративным .Давайте возьмем
book
объект.Так как мы сделали это, мы можем использовать это следующим образом:
Или, если вы знаете мощность генераторов ES6 , вы наверняка сможете сделать приведенный выше код намного короче.
Конечно, вы можете применять такое поведение ко всем объектам, делая
Object
итерацию наprototype
уровне.Кроме того , объекты , которые соответствуют с итерацией протокол может быть использован с помощью новой функции ES2015 распространения оператора , таким образом , мы можем читать значение свойств объекта в виде массива.
Или вы можете использовать назначение деструктурирования :
Вы можете проверить JSFiddle со всем кодом, который я предоставил выше.
источник
начиная с ES06, вы можете получить значения объекта в виде массива с
он возвращает массив значений объекта и не извлекает значения из Prototype !!
MDN DOCS Object.values ()
и для ключей (уже ответили до меня здесь)
источник
В последнем скрипте ES вы можете сделать что-то вроде этого:
источник