У меня есть объект JavaScript, как показано ниже:

var p = {
    "p1": "value1",
    "p2": "value2",
    "p3": "value3"
};

Теперь я хочу просмотреть все p элементы (p1, p2, p3 ...) и получить их ключи и значения. Как я могу это сделать?

Я могу изменить объект JavaScript, если это необходимо. Моя конечная цель - пройтись по нескольким парам ключ-значение, и, если возможно, я хочу избежать использования eval.

3088
Tanmoy 26 Мар 2009 в 09:01

27 ответов

Лучший ответ

Вы можете использовать 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 вместо {{X1 }}, если он не используется, он вернет undefined для именованных свойств и Object.keys() обеспечивает использование только собственных свойств объекта без свойств всей цепочки прототипов

Использование нового Object.entries() метод

Примечание. . Этот метод изначально не поддерживается Internet Explorer. Вы можете рассмотреть возможность использования Polyfill для старых браузеров.

const p = {
    "p1": "value1",
    "p2": "value2",
    "p3": "value3"
};

for (let [key, value] of Object.entries(p)) {
  console.log(`${key}: ${value}`);
}
4277
KostasX 24 Фев 2020 в 05:32

Вы можете добавить простую функцию 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
});

Для тех, кому не нравится метод " for ... in ":

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);
});

Если вы не хотите конфликтовать с другими методами forEach, вы можете назвать его своим уникальным именем.

7
Biber 28 Ноя 2016 в 08:25

Метод Object.keys() возвращает массив собственных перечисляемых свойств данного объекта. Подробнее об этом читайте здесь

var p = {
    "p1": "value1",
    "p2": "value2",
    "p3": "value3"
};

Object.keys(p).map((key)=> console.log(key + "->" + p[key]))
8
George Bailey 16 Ноя 2017 в 21:22

Вот еще один метод, чтобы перебрать объект.

   var p = {
"p1": "value1",
"p2": "value2",
"p3": "value3"
};


Object.keys(p).forEach(key => { console.log(key, p[key]) })
13
Harsh Patel 20 Дек 2017 в 04:42

Начиная с ES06, вы можете получить значения объекта в виде массива с

let arrValues = Object.values( yourObject) ;

Он возвращает массив значений объекта и не извлекает значения из Prototype !!

MDN DOCS Object.values ()

И для ключей (уже ответили до меня здесь)

let arrKeys   = Object.keys(yourObject);
4
yehonatan yehezkel 22 Авг 2018 в 15:41

Вы также можете использовать Object.keys () и перебирать ключи объекта, как показано ниже, чтобы получить значение:

var p = {
    "p1": "value1",
    "p2": "value2",
    "p3": "value3"
};

Object.keys(p).forEach((key)=> {
 console.log(key +' -> '+ p[key]);
});
12
Onera 13 Авг 2019 в 07:14

Через prototype с forEach () , который должен пропустить свойства prototype chain :

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
20
strider 9 Дек 2012 в 05:05

В ECMAScript 5 у вас есть новый подход в полях итераций литерала - Object.keys

Дополнительную информацию вы можете увидеть в MDN

Мой выбор ниже в качестве более быстрого решения в текущих версиях браузеров (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

Для старого браузера у вас есть simple и полная полифилл

< Сильный > UPD :

Сравнение производительности для всех наиболее популярных случаев в этом вопросе на perfjs.info:

буквенная итерация объекта

52
Pencroff 12 Сен 2016 в 22:11
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>
13
TessavWalstijn 19 Мар 2018 в 14:08

Object.entries() функция:

var p = {
	    "p1": "value1",
	    "p2": "value2",
	    "p3": "value3"
	};

for (var i in Object.entries(p)){
	var key = Object.entries(p)[i][0];
	var value = Object.entries(p)[i][1];
	console.log('key['+i+']='+key+' '+'value['+i+']='+value);
}
3
nrb 29 Окт 2018 в 19:21

Использование for-of в Object.keys()

Как:

let object = {
   "key1": "value1"
   "key2": "value2"
   "key3": "value3"
};

for (var key of Object.keys(p)) {
   console.log(key + " : " + object[key])
}
5
Nicolas Cabanas 30 Окт 2019 в 21:05

Я бы сделал это вместо проверки obj.hasOwnerProperty в каждом цикле for ... in.

var obj = {a : 1};
for(var key in obj){
    //obj.hasOwnProperty(key) is not needed.
    console.log(key);
}
//then check if anybody has messed the native object. Put this code at the end of the page.
for(var key in Object){
    throw new Error("Please don't extend the native object");
}
5
Lewis 10 Ноя 2016 в 10:04

Циклы могут быть довольно интересными при использовании чистого 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 только для массивов, который в основном создал новый улучшенный способ циклического перемещения по массивам, при этом оставляя не повторяемые объекты со старым многословным и запутанный цикл for. Но странная часть заключается в том, что этот новый метод forEach не поддерживает break, что привело к множеству других проблем.

По сути, в 2011 году не было реального надежного способа зацикливания в JavaScript, кроме того, что многие популярные библиотеки (jQuery, Underscore и т. Д.) Решили повторно реализовать.

С 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 года. Даже в Chrome необходимо включить этот специальный флаг, чтобы он работал: chrome://flags/#enable-javascript-harmony

Пока это не станет новым стандартом, старый метод все еще можно использовать, но в популярных библиотеках есть альтернативы или даже облегченные альтернативы для тех, кто не использует ни одну из этих библиотек.

6
Nicolas Bouvrette 18 Июн 2016 в 12:55
    var p =[{"username":"ordermanageadmin","user_id":"2","resource_id":"Magento_Sales::actions"},
{"username":"ordermanageadmin_1","user_id":"3","resource_id":"Magento_Sales::actions"}]
for(var value in p) {
    for (var key in value) {
        if (p.hasOwnProperty(key)) {
            console.log(key + " -> " + p[key]);
        }
    }
}
5
Zakaria Acharki 14 Сен 2018 в 17:51

Только код 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
}
8
Peter Mortensen 16 Июн 2016 в 17:34

Если вы хотите перебрать не- а также перечисляемые свойства , вы можете использовать Object.getOwnPropertyNames(obj), чтобы вернуть массив всех свойств (перечисляемых или нет), найденных непосредственно в данном объекте.

var obj = Object.create({}, {
  // non-enumerable property
  getFoo: {
    value: function() { return this.foo; },
    enumerable: false
  }
});

obj.foo = 1; // enumerable property

Object.getOwnPropertyNames(obj).forEach(function (name) {
  document.write(name + ': ' + obj[name] + '<br/>');
});
4
Dheeraj V.S. 11 Ноя 2015 в 05:26

Object.keys (obj): Array

извлекает все строковые ключи всех перечисляемых собственных (не наследуемых) свойств.

Таким образом, он дает тот же список ключей, что и вы, проверяя каждый ключ объекта с помощью hasOwnProperty. Вам не нужна эта дополнительная тестовая операция, а Object.keys( obj ).forEach(function( key ){}) должен быть быстрее. Давайте докажем это:

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 у меня есть следующие результаты

  • Подход Object.keys занял 40,21101451665163 миллисекунд.
  • для ... в / hasOwnProperty подход занял 98.26163508463651 миллисекунд.

PS . в Chrome разница еще больше http://codepen.io/dsheiko/pen/JdrqXa

PS2: в ES6 (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);
});
13
Dmitry Sheiko 22 Июн 2015 в 11:33

Поскольку es2015 становится все более популярным, я публикую этот ответ, который включает использование генератора и итератора для плавного перебора пар [key, value]. Как это возможно в других языках, например, Ruby.

Хорошо, вот код:

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.

Надеюсь, это помогло кому-то.

< Сильный > EDIT :

ES2017 будет включать Object.entries, что сделает итерацию по парам [key, value] в объектах еще проще. Теперь известно, что это будет частью стандарта в соответствии с ts39 сценическая информация.

Я думаю, что пришло время обновить мой ответ, чтобы он стал еще свежее, чем сейчас.

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}`);
}

Вы можете узнать больше об использовании на страница MDN

27
FieryCod 30 Июл 2017 в 14:34

В ES6 у нас есть хорошо известные символы для представления некоторых ранее внутренних методов, вы можете использовать его, чтобы определить, как работают итераторы для этого объекта:

var p = {
    "p1": "value1",
    "p2": "value2",
    "p3": "value3",
    *[Symbol.iterator]() {
        yield *Object.keys(this);
    }
};

[...p] //["p1", "p2", "p3"]

Это даст тот же результат, что и использование for ... в цикле es6.

for(var key in p) {
    console.log(key);
}

Но важно знать, какие возможности у вас сейчас есть, используя es6!

5
Bamieh 20 Сен 2016 в 09:04

Вы можете просто перебрать его так:

for (var key in p) {
  alert(p[key]);
}

Обратите внимание, что key не будет принимать значение свойства, это просто значение индекса.

49
billynoah 9 Окт 2018 в 15:11

Вы должны использовать цикл for-in .

Но будьте очень осторожны при использовании этого вида цикла, потому что это зациклит все свойства в цепочке прототипов .

Поэтому при использовании циклов for-in всегда используйте метод 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
}
340
Vitim.us 24 Фев 2016 в 10:51

Если кому-то нужно пройти через массив объектов с условием :

var arrayObjects = [{"building":"A", "status":"good"},{"building":"B","status":"horrible"}];

for (var i=0; i< arrayObjects.length; i++) {
  console.log(arrayObjects[i]);
  
  for(key in arrayObjects[i]) {      
    
      if (key == "status" && arrayObjects[i][key] == "good") {
        
          console.log(key + "->" + arrayObjects[i][key]);
      }else{
          console.log("nothing found");
      }
   }
}
4
Tadas V. 22 Июл 2016 в 03:48

После просмотра всех ответов здесь hasOwnProperty не требуется для моего собственного использования, потому что мой объект json чист; нет никакого смысла в добавлении какой-либо дополнительной обработки javascript. Это все, что я использую:

for (var key in p) {
    console.log(key + ' => ' + p[key]);
    // key is key
    // value is p[key]
}
20
Francis Lewis 18 Авг 2011 в 20:50

Что касается ES6, я бы хотел добавить свою собственную ложку сахара и предоставить еще один подход для перебора свойств объекта.

Поскольку обычный объект JS не является итеративным итерацией , мы не можем использовать цикл for..of для перебора его содержимого. Но никто не может помешать нам сделать его итеративным .

Давайте у нас будет book объект.

let book = {
  title: "Amazing book",
  author: "Me",
  pages: 3
}

book[Symbol.iterator] = function(){

  let properties = Object.keys(this); // returns an array with property names
  let counter = 0;
  let isDone = false;

  let next = () => {
    if(counter >= properties.length){
      isDone = true;
    }
    return { done: isDone, value: this[properties[counter++]] }
  }

  return { next };
}

Так как мы сделали это, мы можем использовать это следующим образом:

for(let pValue of book){
  console.log(pValue);
}
------------------------
Amazing book
Me
3

Или, если вы знаете мощь ES6 генераторов, так что вы, конечно, можете сделать приведенный выше код намного короче.

book[Symbol.iterator] = function *(){

  let properties = Object.keys(this);
  for (let p of properties){
    yield this[p];
  }

}

Конечно, вы можете применить такое поведение ко всем объектам, сделав Object итеративным на уровне prototype.

Object.prototype[Symbol.iterator] = function() {...}

Кроме того, объекты, соответствующие итерируемому протоколу, могут использоваться с новой функцией ES2015 spread, таким образом, мы можем прочитать значения свойств объекта в виде массива.

let pValues = [...book];
console.log(pValues);
-------------------------
["Amazing book", "Me", 3]

Или вы можете использовать назначение деструктурирования:

let [title, , pages] = book; // notice that we can just skip unnecessary values
console.log(title);
console.log(pages);
------------------
Amazing book
3

Вы можете проверить JSFiddle со всем кодом, который я предоставил выше.

4
Artyom Pranovich 2 Сен 2016 в 13:56
for(key in p) {
  alert( p[key] );
}

Примечание: вы можете делать это над массивами, но вы будете выполнять итерации по length и другим свойствам.

22
Kristian 3 Ноя 2012 в 21:46

В последнем скрипте ES вы можете сделать что-то вроде этого:

Object.entries(p);
3
Ankit 11 Сен 2018 в 05:55

В ECMAScript 5 вы можете объединить {{X0} } и Array.prototype.forEach() :

var obj = { first: "John", last: "Doe" };

Object.keys(obj).forEach(function(key) {
    console.log(key, obj[key]);
});

ECMAScript 6 добавляет for...of :

for (const key of Object.keys(obj)) {
    console.log(key, obj[key]);
}

ECMAScript 8 добавляет Object.entries() который избегает необходимости искать каждое значение в исходном объекте:

Object.entries(obj).forEach(
    ([key, value]) => console.log(key, value)
);

Вы можете объединить for...of, деструктуризацию и Object.entries:

for (const [key, value] of Object.entries(obj)) {
    console.log(key, value);
}

И Object.keys(), и Object.entries() повторяют свойства в том же порядке, что и цикл for...in , но игнорируют цепочку прототипов . Только собственные перечисляемые свойства объекта повторяются.

1078
T.J. Crowder 15 Май 2019 в 17:17