Как пройти через цикл или перечислить объект JavaScript? - PullRequest
2522 голосов
/ 26 марта 2009

У меня есть объект JavaScript, подобный следующему:

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

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

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

Ответы [ 36 ]

4 голосов
/ 20 сентября 2016

В 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!

4 голосов
/ 01 сентября 2016

Учитывая 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 голосов
/ 09 июля 2018

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

let arrValues = Object.values( yourObject) ;

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

MDN DOCS Object.values ​​()

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

let arrKeys   = Object.keys(yourObject);
4 голосов
/ 09 июля 2015

Я бы сделал это вместо проверки 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");
}
3 голосов
/ 12 сентября 2015

Если вы хотите выполнить итерацию для не перечисляемых свойств , вы можете использовать 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/>');
});
3 голосов
/ 22 июля 2016

Если кому-то нужно перебрать arrayObjects с условием :

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");
      }
   }
}
3 голосов
/ 11 сентября 2018

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

Object.entries(p);
2 голосов
/ 24 октября 2018

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);
}
1 голос
/ 07 февраля 2019

Это как перебрать объект javascript и поместить данные в таблицу.

<body>
<script>
function createTable(objectArray, fields, fieldTitles) {
  let body = document.getElementsByTagName('body')[0];
  let tbl = document.createElement('table');
  let thead = document.createElement('thead');
  let thr = document.createElement('tr');

  for (p in objectArray[0]){
    let th = document.createElement('th');
    th.appendChild(document.createTextNode(p));
    thr.appendChild(th);
    
  }
 
  thead.appendChild(thr);
  tbl.appendChild(thead);

  let tbdy = document.createElement('tbody');
  let tr = document.createElement('tr');
  objectArray.forEach((object) => {
    let n = 0;
    let tr = document.createElement('tr');
    for (p in objectArray[0]){
      var td = document.createElement('td');
      td.appendChild(document.createTextNode(object[p]));
      tr.appendChild(td);
      n++;
    };
    tbdy.appendChild(tr);    
  });
  tbl.appendChild(tbdy);
  body.appendChild(tbl)
  return tbl;
}

createTable([
              {name: 'Banana', price: '3.04'}, // k[0]
              {name: 'Orange', price: '2.56'},  // k[1]
              {name: 'Apple', price: '1.45'}
           ])
</script>
1 голос
/ 10 октября 2017

У меня была похожая проблема при использовании Angular, вот решение, которое я нашел.

Шаг 1. Получить все ключи объекта. используя Object.keys. Этот метод возвращает массив собственных перечисляемых свойств данного объекта.

Шаг 2. Создать пустой массив. Это место, где будут жить все свойства, так как ваш новый цикл ngFor будет указывать на этот массив, мы должны перехватить их все. Шаг 3. Выполните итерацию и добавьте все ключи в созданный вами массив. Вот как это выглядит в коде.

    // Evil response in a variable. Here are all my vehicles.
let evilResponse = { 
  "car" : 
    { 
       "color" : "red",
       "model" : "2013"
    },
   "motorcycle": 
    { 
       "color" : "red",
       "model" : "2016"
    },
   "bicycle": 
    { 
       "color" : "red",
       "model" : "2011"
    }
}
// Step 1. Get all the object keys.
let evilResponseProps = Object.keys(evilResponse);
// Step 2. Create an empty array.
let goodResponse = [];
// Step 3. Iterate throw all keys.
for (prop of evilResponseProps) { 
    goodResponse.push(evilResponseProps[prop]);
}

Вот ссылка на оригинальный пост. https://medium.com/@papaponmx/looping-over-object-properties-with-ngfor-in-angular-869cd7b2ddcc

...