У меня есть объект JavaScript, подобный следующему:
var p = {
"p1": "value1",
"p2": "value2",
"p3": "value3"
};
Теперь я хочу перебрать все элементы p
(p1
, p2
, p3
...) и получить их ключи и значения. Как я могу это сделать?
При необходимости я могу модифицировать объект JavaScript. Моя конечная цель - перебрать несколько пар ключ-значение и, по возможности, избежать использования eval
.
Вы можете использовать цикл for-in
, как показано другими. Однако, вы также должны убедиться, что ключ, который вы получаете, является фактическим свойством объекта, а не приходит из прототипа.
Вот фрагмент:.
var p = {
"p1": "value1",
"p2": "value2",
"p3": "value3"
};
for (var key in p) {
if (p.hasOwnProperty(key)) {
console.log(key + " -> " + p[key]);
}
}
For-of с альтернативой Object.keys():.
var p = {
0: "value1",
"b": "value2",
key: "value3"
};
for (var key of Object.keys(p)) {
console.log(key + " -> " + p[key])
}
Обратите внимание на использование for-of
вместо for-in
, если его не использовать, то он вернет неопределенное значение для именованных свойств, а Object.keys() гарантирует использование только собственных свойств объекта без свойств всей цепочки прототипов
В соответствии с ECMAScript 5, Вы можете совместить объект .ключи()
и массива.прототип.по каждому элементу()
:
var obj = { first: "John", last: "Doe" };
Object.keys(obj).forEach(function(key) {
console.log(key, obj[key]);
});
В ECMAScript 6 добавляет Для...в`:
for (const key of Object.keys(obj)) {
console.log(key, obj[key]);
}
В ECMAScript 8 добавляет объекта.записи()
, что позволяет избежать обращения к каждому значению в исходном объекте:
Object.entries(obj).forEach(
([key, value]) => console.log(key, value)
);
Вы можете комбинировать для...Из, деструктурируется, и объект.записи:
for (const [key, value] of Object.entries(obj)) {
console.log(key, value);
}
Оба Объекта.ключи()и
объект.записи()` перебираем свойства в том же порядке, как для...в цикле но игнорировать цепочке прототипов. Только объект's собственное перечислимые свойства итерированных.
Вы должны использовать для-в петлю
Но будьте очень осторожны при использовании этого вида петли, потому что это петля все свойства по цепочке прототипов.
Поэтому, при использовании к-во петель, всегда использовать метод hasOwnProperty
метод, чтобы определить, если текущая собственность в итерации-это действительно свойство объекта вы'повторно проверять на:
for (var prop in p) {
if (!p.hasOwnProperty(prop)) {
//The current property is not a direct property of p
continue;
}
//Do your logic with the property here
}
На вопрос, выиграл'т быть полным, если мы не'т упомянуть про альтернативные методы для перебора объектов.
На сегодняшний день многие известные библиотеки JavaScript предоставить свои методы для итерации по коллекции, т. е. за массивы, объектов и массив-как объекты. Эти методы удобны в использовании и полностью совместимый с любым браузером.
и jQuery.каждый()
метод. Это может использоваться, чтобы легко перебрать все объекты и массивы:$.каждый(объект, функция(ключ, значение) { консоль.журнал(ключ, значение); });
_.каждый()
, который перебирает список элементов, получая каждый по очереди предоставленной функции (обратите внимание на порядок аргументов в iteratee функция!):_.каждый(объект, функция(значение, ключ) { консоль.журнал(ключ, значение); });
_.по каждому элементу()
(или его'ы псевдоним _.каждый()
) используется для перебора как объекты и массивы, однако (!) объектов, свойство "length" обрабатываются как массивы, и чтобы избежать этого рекомендуется использовать _.Форин()
и _.forOwn()
методы (они также имеют "значение" аргумент на первом месте):_.Форин(объект, функция(значение, ключ) { консоль.журнал(ключ, значение); });
_.проходит Форин () по *собственные и наследуемые* свойств объекта, в то время как
_.forOwn()выполняется только за *собственный* свойства объекта (в основном проверка в отношении функции метода hasOwnProperty
). Для простых объектов и литералов объектов, любой из этих методов будет работать нормально.
Как правило, все описанные методы имеют одинаковое поведение с любыми предоставленные объекты. Кроме того, используя родной для..в петлю обычно будет быстрее, чем любые абстракции, например, на jQuery.каждый (), эти методы значительно проще в использовании, требует меньше кодирования и обеспечивают лучшую обработку ошибок.
В ECMAScript 5 у вас есть новый подход в итерации поля литерал - объект.ключи`
Более подробную информацию вы можете посмотреть на МДН
Мой выбор ниже в качестве быстрого решения в текущих версиях браузеров (Chrome30, в IE10, FF25)
var keys = Object.keys(p),
len = keys.length,
i = 0,
prop,
value;
while (i < len) {
prop = keys[i];
value = p[prop];
i += 1;
}
Вы можете сравнить эффективность такого подхода с различными реализациями на jsperf.com:
Поддержка браузеров вы можете посмотреть на Kangax'таблица совместимости
Для старого браузера у вас есть простая и полный полифилл
УПД:
сравнение производительности на всех самых популярных дел в этом вопросе на perfjs.info
:
Вы можете просто выполнить итерацию по нему, например:
for (var key in p) {
alert(p[key]);
}
Обратите внимание, что key
не будет принимать значение свойства, это просто индексное значение.
Предисловие:
Вот в 2018 году, ваши варианты для цикла по объекту's свойства (некоторые примеры следуют списка):
на-на
[уведомление, спец] &ампер;mdash; не петлю структуру, которая перебирает имена объекта'ы перечисляемую свойства, в том числе и наследственными, чьи имена строкОбъект.ключи
[уведомление, спец] &ампер;mdash; не функция, обеспечивая множество имен объекта'ы собственные, перечисляемую свойства, имена которых являются строками.Объект.значения
[уведомление, спец] &ампер;mdash; не функция предоставления массив ценности объекта'ы собственные, перечисляемую свойства.Объект.записи
[уведомление, спец] &ампер;mdash; не функция предоставления массив имен и значения объекта'ы собственные, перечисляемую свойства (каждый элемент массива [имя, значение]
массив).Объект.getOwnPropertyNames
[уведомление, спец] &ампер;mdash; не функция, обеспечивая множество имен объекта'ы собственный свойства (даже не перечисли те), чьи имена строк.Объект.getOwnPropertySymbols
[уведомление, спец] &ампер;mdash; не функция, обеспечивая множество имен объекта'ы собственный свойства (даже не перечисли те), чьи имена являются символами..getPrototypeOf
[уведомление, спец] и использовать объект.getOwnPropertyNames
, `объект.getOwnPropertySymbols " или " отражать.ownKeys на каждый объект в цепочке прототипов (например, в нижней части этого ответа).Со всеми из них, за исключением на-на
, вы'd с помощью какой-то циклы на массив (для
, НА-НА
, объекту
, и т. д.).
Примеры:
- в
:
в
// A prototype object to inherit from, with a string-named property
const p = {answer: 42};
// The object we'll look at, which inherits from `p`
const o = Object.create(p);
// A string-named property
o.question = "Life, the Universe, and Everything";
// A symbol-named property
o[Symbol("author")] = "Douglas Adams";
for (const name in o) {
const value = o[name];
console.log(`${name} = ${value}`);
}
в
Объект.ключи
(с на-на
петли, но вы можете использовать любые циклы):
в
// A prototype object to inherit from, with a string-named property
const p = {answer: 42};
// The object we'll look at, which inherits from `p`
const o = Object.create(p);
// A string-named property
o.question = "Life, the Universe, and Everything";
// A symbol-named property
o[Symbol("author")] = "Douglas Adams";
for (const name of Object.keys(o)) {
const value = o[name];
console.log(`${name} = ${value}`);
}
в
`Объект.значений:
в
// A prototype object to inherit from, with a string-named property
const p = {answer: 42};
// The object we'll look at, which inherits from `p`
const o = Object.create(p);
// A string-named property
o.question = "Life, the Universe, and Everything";
// A symbol-named property
o[Symbol("author")] = "Douglas Adams";
for (const value of Object.values(o)) {
console.log(`${value}`);
}
в
`Объект.записей:
в
// A prototype object to inherit from, with a string-named property
const p = {answer: 42};
// The object we'll look at, which inherits from `p`
const o = Object.create(p);
// A string-named property
o.question = "Life, the Universe, and Everything";
// A symbol-named property
o[Symbol("author")] = "Douglas Adams";
for (const [name, value] of Object.entries(o)) {
console.log(`${name} = ${value}`);
}
в
Объект.getOwnPropertyNames
:
в
// A prototype object to inherit from, with a string-named property
const p = {answer: 42};
// The object we'll look at, which inherits from `p`
const o = Object.create(p);
// A string-named property
o.question = "Life, the Universe, and Everything";
// A symbol-named property
o[Symbol("author")] = "Douglas Adams";
for (const name of Object.getOwnPropertyNames(o)) {
const value = o[name];
console.log(`${name} = ${value}`);
}
в
Объект.getOwnPropertySymbols
:
в
// A prototype object to inherit from, with a string-named property
const p = {answer: 42};
// The object we'll look at, which inherits from `p`
const o = Object.create(p);
// A string-named property
o.question = "Life, the Universe, and Everything";
// A symbol-named property
o[Symbol("author")] = "Douglas Adams";
for (const name of Object.getOwnPropertySymbols(o)) {
const value = o[name];
console.log(`${String(name)} = ${value}`);
}
в
Отражают.ownKeys`:
в
// A prototype object to inherit from, with a string-named property
const p = {answer: 42};
// The object we'll look at, which inherits from `p`
const o = Object.create(p);
// A string-named property
o.question = "Life, the Universe, and Everything";
// A symbol-named property
o[Symbol("author")] = "Douglas Adams";
for (const name of Reflect.ownKeys(o)) {
const value = o[name];
console.log(`${String(name)} = ${value}`);
}
в
Все объекты, в том числе по наследству неперечислимый из них:
в
// A prototype object to inherit from, with a string-named property
const p = {answer: 42};
// The object we'll look at, which inherits from `p`
const o = Object.create(p);
// A string-named property
o.question = "Life, the Universe, and Everything";
// A symbol-named property
o[Symbol("author")] = "Douglas Adams";
for (let depth = 0, current = o; current; ++depth, current = Object.getPrototypeOf(current)) {
for (const name of Reflect.ownKeys(current)) {
const value = o[name];
console.log(`[${depth}] ${String(name)} = ${String(value)}`);
}
}
.as-console-wrapper {
max-height: 100% !important;
}
в
С es2015 становится все более и более популярным, я отправляю этот ответ, который включает в себя использование генератора и итератор плавно перебирать [ключ, значение]
пар. Как это возможно в других языках, например, рубиновым.
ОК, Вот код:
const MyObject = {
'a': 'Hello',
'b': 'it\'s',
'c': 'me',
'd': 'you',
'e': 'looking',
'f': 'for',
[Symbol.iterator]: function* () {
for (const i of Object.keys(this)) {
yield [i, this[i]];
}
}
};
for (const [k, v] of MyObject) {
console.log(`Here is key ${k} and here is value ${v}`);
}
Вся информация о том, как можно сделать итератор и генератор вы можете найти на странице разработчика Mozilla.
Надеюсь, что это помогло кому-то.
Редактировать:
ES2017 будет включать в объект.записи, делают перебора `пар[ключ, значение] в объекты еще проще. Сейчас известно, что она станет частью стандартного согласно ts39 стадии сведения.
Я думаю, что это время, чтобы обновить мой ответ, чтобы она стала еще более свежее, чем он's теперь.
const MyObject = {
'a': 'Hello',
'b': 'it\'s',
'c': 'me',
'd': 'you',
'e': 'looking',
'f': 'for',
};
for (const [k, v] of Object.entries(MyObject)) {
console.log(`Here is key ${k} and here is value ${v}`);
}
Вы можете узнать больше об использовании по Уведомление Страница
for(key in p) {
alert( p[key] );
}
Примечание: вы можете сделать это над массивами, но вы'будете итерировать над length
и другими свойствами.
После просмотра всех ответов здесь, метод hasOwnProperty разве'т, необходимое для моего собственного использования, потому что мой JSON-объект очистки; там's действительно нет смысла добавлять какие-либо дополнительные обработки JavaScript. Это все, что я'м с использованием:
for (var key in p) {
console.log(key + ' => ' + p[key]);
// key is key
// value is p[key]
}
через прототип с еогеасп() который должен пропустить от цепочки прототипов свойства:
Object.prototype.each = function(f) {
var obj = this
Object.keys(obj).forEach( function(key) {
f( key , obj[key] )
});
}
//print all keys and values
var obj = {a:1,b:2,c:3}
obj.each(function(key,value) { console.log(key + " " + value) });
// a 1
// b 2
// c 3
Это'с интересными людьми в этих ответах затронули оба объекта.ключи () " и " для...Из-да, но не объединил их:
в
var map = {well:'hello', there:'!'};
for (let key of Object.keys(map))
console.log(key + ':' + map[key]);
<суб>вы можете'Т просто Для...
в качестве объекта
, потому что он's не итератор, и для...indexили
.еогеасп()Инг
объект.ключи () - это некрасиво и неэффективно.<БР/>
Я'м рад, что большинство людей воздерживается от за...
(С или без проверки.метод hasOwnProperty()`) так, что's также немного грязный, так что кроме моего ответа выше, я'м здесь, чтобы сказать...</суб>
Вы можете сделать обычный предмет объединений перебирать! Ведет себя просто как карты с прямое использование фантазии для...от`<БР/> Демо работает в Chrome и FF (я предполагаю, ЕС6 только)
var ordinaryObject = {well:'hello', there:'!'};
for (let pair of ordinaryObject)
//key:value
console.log(pair[0] + ':' + pair[1]);
//or
for (let [key, value] of ordinaryObject)
console.log(key + ':' + value);
Так долго, как вы включите мой ШИМ ниже:
//makes all objects iterable just like Maps!!! YAY
//iterates over Object.keys() (which already ignores prototype chain for us)
Object.prototype[Symbol.iterator] = function() {
var keys = Object.keys(this)[Symbol.iterator]();
var obj = this;
var output;
return {next:function() {
if (!(output = keys.next()).done)
output.value = [output.value, obj[output.value]];
return output;
}};
};
Без создания объекта недвижимого карте, что не'т иметь приятный синтаксический сахар.
var trueMap = new Map([['well', 'hello'], ['there', '!']]);
for (let pair of trueMap)
console.log(pair[0] + ':' + pair[1]);
В самом деле, с этим ШИМ, если ты все равно хотел воспользоваться картой's другая функциональность (без заклинивать их всех), но все равно хотел использовать аккуратно нотация объектов, поскольку объекты итерируемыми теперь вы можете просто сделать карту из него!
//shown in demo
var realMap = new Map({well:'hello', there:'!'});
Для тех, кто не'т, как в оболочку, или чехарда с "прототипом" в общем, не стесняйтесь сделать функцию на окно вместо этого, называя это что-то вроде getObjIterator()
то;
//no prototype manipulation
function getObjIterator(obj) {
//create a dummy object instead of adding functionality to all objects
var iterator = new Object();
//give it what the shim does but as its own local property
iterator[Symbol.iterator] = function() {
var keys = Object.keys(obj)[Symbol.iterator]();
var output;
return {next:function() {
if (!(output = keys.next()).done)
output.value = [output.value, obj[output.value]];
return output;
}};
};
return iterator;
}
Теперь вы можете просто назвать это как обычная функция, пострадавших ничего не
var realMap = new Map(getObjIterator({well:'hello', there:'!'}))
или
for (let pair of getObjIterator(ordinaryObject))
[Там's нет причин, почему бы't работа.](
)Добро пожаловать в будущее.
Вот еще один способ, чтобы выполнить итерации через объект.
в
в
ВАР Р = { на "П1" и: "по значение1" и, на "П2" и: "и значение2" и, на "П3" и: "и значение3"и };
Объект.ключи(п).по каждому элементу(ключ => { консоли.журнал(ключ, п[ключ]) })
в
объект.ключи(объект) : массив в<строка>
извлекает все строки значением ключей всех собственных перечислимых (не наследуемые) свойства.
Поэтому он дает тот же самый список ключей, как вы предполагаете путем испытания каждого ключевого объекта с помощью метода hasOwnProperty. Вы Don'т необходимость, что дополнительные работы тест, чем и объект.ключи( объект ).(функцию foreach( ключ ){})` должен быть быстрее. Позвольте'ы это доказать:
в
var uniqid = function(){
var text = "",
i = 0,
possible = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
for( ; i < 32; i++ ) {
text += possible.charAt( Math.floor( Math.random() * possible.length ) );
}
return text;
},
CYCLES = 100000,
obj = {},
p1,
p2,
p3,
key;
// Populate object with random properties
Array.apply( null, Array( CYCLES ) ).forEach(function(){
obj[ uniqid() ] = new Date()
});
// Approach #1
p1 = performance.now();
Object.keys( obj ).forEach(function( key ){
var waste = obj[ key ];
});
p2 = performance.now();
console.log( "Object.keys approach took " + (p2 - p1) + " milliseconds.");
// Approach #2
for( key in obj ) {
if ( obj.hasOwnProperty( key ) ) {
var waste = obj[ key ];
}
}
p3 = performance.now();
console.log( "for...in/hasOwnProperty approach took " + (p3 - p2) + " milliseconds.");
в
В моем Firefox у меня следующие результаты
ПС. на Хром разница еще больше http://codepen.io/dsheiko/pen/JdrqXa
ПС2: в ЕС6 (в ECMAScript 2015) Вы можете итерировать итерируемый объект лучше:
в
let map = new Map().set('a', 1).set('b', 2);
for (let pair of map) {
console.log(pair);
}
// OR
let map = new Map([
[false, 'no'],
[true, 'yes'],
]);
map.forEach((value, key) => {
console.log(key, value);
});
в
в
var p = {
"p1": "value1",
"p2": "value2",
"p3": "value3"
};
for (var key in p) {
if (p.hasOwnProperty(key)) {
console.log(key + " = " + p[key]);
}
}
<p>
Output:<br>
p1 = values1<br>
p2 = values2<br>
p3 = values3
</p>
в
Вы также можете использовать объект.ключи() и перебирать ключи объекта, как показано ниже, чтобы получить значение:
в
var p = {
"p1": "value1",
"p2": "value2",
"p3": "value3"
};
Object.keys(p).forEach((key)=> {
console.log(key +' -> '+ p[key]);
});
в
Объект.ключи()
метод возвращает массив заданного объекта'собственных перечислимых свойств. Подробнее об этом здесь
в
var p = {
"p1": "value1",
"p2": "value2",
"p3": "value3"
};
Object.keys(p).map((key)=> console.log(key + "->" + p[key]))
в
Вы можете добавить простой цикл foreach функция для всех объектов, так что вы можете автоматически цикл через любой объект:
Object.defineProperty(Object.prototype, 'forEach', {
value: function (func) {
for (var key in this) {
if (!this.hasOwnProperty(key)) {
// skip loop if the property is from prototype
continue;
}
var value = this[key];
func(key, value);
}
},
enumerable: false
});
Для тех людей, которые Дон'т, как в "ПО ... в" и-способ:
Object.defineProperty(Object.prototype, 'forEach', {
value: function (func) {
var arr = Object.keys(this);
for (var i = 0; i < arr.length; i++) {
var key = arr[i];
func(key, this[key]);
}
},
enumerable: false
});
Теперь, вы можете просто позвонить:
p.forEach (function(key, value){
console.log ("Key: " + key);
console.log ("Value: " + value);
});
Если вы Don'т хотите, чтобы получить конфликтов с другими объекту-методы вы можете назвать ее своим уникальным именем.
Только JavaScript код без зависимостей:
var p = {"p1": "value1", "p2": "value2", "p3": "value3"};
keys = Object.keys(p); // ["p1", "p2", "p3"]
for(i = 0; i < keys.length; i++){
console.log(keys[i] + "=" + p[keys[i]]); // p1=value1, p2=value2, p3=value3
}
Петли могут быть довольно интересные при использовании чистого JavaScript. Похоже, что только ECMA6 (новая спецификация на JavaScript 2015) есть петельки под контролем. К сожалению, как я'м пишу это, как браузеры и популярные интегрированные среды разработки (IDE) все еще пытаются поддерживать совершенно новые колокола и свистки.
На первый взгляд, здесь является то, что объект JavaScript петли перед ECMA6:
for (var key in object) {
if (p.hasOwnProperty(key)) {
var value = object[key];
console.log(key); // This is the key;
console.log(value); // This is the value;
}
}
Кроме того, я знаю, что это выходит за рамки этого вопроса, но в 2011 году, в ECMAScript 5.1 добавлена объекту
метод для массивов только что фактически создал новый усовершенствованный способ перебора массивов в то же время оставляя без итерируемые объекты со старой многословный и запутанный для
петли. Но странно то, что этот новый метод forEachне поддерживает
разрыв`, который привел к всякие другие проблемы.
В основном в 2011 году, есть не настоящий надежный способ, чтобы цикл в JavaScript, кроме того, что много популярных библиотек (jQuery и подчеркивания и т. д.) решил повторно реализовать.
По состоянию на 2015 год, теперь мы имеем "из коробки" способ петля (и сломать) любого типа объекта (включая массивы и строки). Вот то, что цикл в JavaScript будет выглядеть в конечном итоге, когда эта рекомендация станет мейнстримом:
for (let [key, value] of Object.entries(object)) {
console.log(key); // This is the key;
console.log(value); // This is the value;
}
Обратите внимание, что большинство браузеров выиграл'т поддерживать код выше состоянию на 18 июня 2016. Даже в Хром вам необходимо включить этот специальный флаг для того, чтобы работать: `хром://флаги/#включить-и JavaScript-гармония ...
Пока это будет новый стандарт, старый метод по-прежнему может использоваться, но есть и альтернативы в популярных библиотек или даже легкий альтернатив для тех, кто не'т использовать любой из этих библиотек.