Итерация по свойствам объекта

 var obj = {
  name: "Simon",
  age: "20",
  clothing: {
   style: "simple",
   hipster: false
  }
 }

 for(var propt in obj){
  alert(propt + ': ' + obj[propt]);
 }

Как работает переменная propt представлять свойства объекта? Это не встроенный метод или свойство. Тогда почему он подходит к каждому свойству объекта?

33 ответа

Перебор свойств требует этого дополнительного hasOwnProperty проверять:

for (var property in object) {
    if (object.hasOwnProperty(property)) {
        // do stuff
    }
}

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

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

Начиная с JavaScript 1.8.5 вы можете использовать Object.keys(obj) получить массив свойств, определенных для самого объекта (те, которые возвращают true для obj.hasOwnProperty(key)).

Object.keys(obj).forEach(function(key,index) {
    // key: the name of the object key
    // index: the ordinal position of the key within the object 
});

Это лучше (и более читабельно), чем использование цикла for-in.

Поддерживается в следующих браузерах:

  • Firefox (Gecko): 4 (2,0)
  • Хром: 5
  • Internet Explorer: 9

Дополнительную информацию смотрите в справочнике Mozilla Developer Network Object.keys ().

Девочки и парни, мы находимся в 2017 году, и у нас не так много времени для набора текста... Итак, давайте сделаем этот крутой новый модный ECMAScript 2016:

Object.keys(obj).forEach(e => console.log(`key=${e}  value=${obj[e]}`));

В следующих версиях ES вы можете использовать Object.entries:

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

или же

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

Если вы просто хотите перебрать значения, используйте Object.values:

for (const value of Object.values(obj)) { }

или же

Object.values(obj).forEach(value => ...)

Это for...in statement ( MDN, спецификация ECMAScript).

Вы можете прочитать это как " ДЛЯ каждого свойства в obj объект, присвойте каждое свойство переменной PROPT по очереди ".

Это просто for...in петля. Проверьте документацию в Mozilla.

if(Object.keys(obj).length) {
    Object.keys(obj).forEach(key => {
        console.log("\n" + key + ": " + obj[key]);
    });
}

// *** Explanation line by line ***

// Explaining the bellow line
// It checks if obj has at least one property. Here is how:
// Object.keys(obj) will return an array with all keys in obj.
// Keys are just the regular incremental numbers starting from 0.
// If there is no keys in obj, it will return empty array = []
// Then it will get its length. At this point, it checks: 
// If it has at least one element, it means it's bigger than 0 
// which evaluates to true and the bellow code will be executed.
// Else means it's length = 0 which evaluates to false
// NOTE: you can use Object.hasOwnProperty() instead of Object.keys(obj).length
if(Object.keys(obj).length) {

    // Explaining the bellow line
    // Just like in the previous line, this returns an array with
    // all keys in obj (because if code execution got here, it means 
    // obj has keys.) 
    // Then just invoke built-in javascript forEach() to loop
    // over each key in returned array and calls a call back function 
    // on each array element (key), using ES6 arrow function (=>)
    // Or you can just use a normal function ((key) { blah blah }).
    Object.keys(obj).forEach(key => {

        // The bellow line prints out all keys with their 
        // respective value in obj.
        // key comes from the returned array in Object.keys(obj)
        // obj[key] returns the value of key in obj
        console.log("\n" + key + ": " + obj[key]);
    });
}

Если ваша среда поддерживает ES2017, я бы порекомендовал Object.entries:

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

Как показано в документации Mozillas Object.entries():

Метод Object.entries () возвращает массив пар перечислимого свойства [key, value] собственного объекта данного объекта в том же порядке, что и в цикле for... in (отличие состоит в том, что цикл for-in перечисляет свойства в цепи прототипа).

По сути, с Object.entries мы можем отказаться от следующего дополнительного шага, который необходим для старшего цикла for... in:

// This step is not necessary with Object.entries
if (object.hasOwnProperty(property)) {
  // do stuff
}

Ответ Доминика идеален, я просто предпочитаю делать так, потому что читать чище:

for (var property in object) {
    if (!object.hasOwnProperty(property)) continue;

    // Do stuff...
}

jquery позволяет вам сделать это сейчас:

$.each( obj, function( key, value ) {
  alert( key + ": " + value );
});

Цикл for... in представляет каждое свойство объекта, поскольку оно похоже на цикл for. Вы определили propt в цикле for... in, выполнив:

    for(var propt in obj){
alert(propt + ': ' + obj[propt]);
}

Цикл for... in перебирает перечисляемые свойства объекта. Независимо от того, какую переменную вы определяете или помещаете в цикл for... in, она изменяется каждый раз, когда переходит к следующему свойству, которое она выполняет. Переменная в цикле for... in перебирает ключи, но ее значение является значением ключа. Например:

    for(var propt in obj) {
      console.log(propt);//logs name
      console.log(obj[propt]);//logs "Simon"
    }

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

Надеюсь, это поможет.

let obj = {"a": 3, "b": 2, "6": "a"}

Object.keys(obj).map((item) => {console.log("item", obj[item])})

// a
// 3
// 2

Чтобы добавить использование ES2015 Reflect.ownKeys(obj) а также перебирая свойства через итератор.

Например:

let obj = { a: 'Carrot', b: 'Potato', Car: { doors: 4 } };

может быть повторен

// logs each key
Reflect.ownKeys(obj).forEach(key => console.log(key));

Если вы хотите выполнить итерацию непосредственно над значениями ключей объекта, вы можете определить iteratorтак же, как итераторы JavaScipts по умолчанию для строк, массивов, типизированных массивов, Map и Set.

JS попытается выполнить итерацию через свойство итератора по умолчанию, которое должно быть определено как Symbol.iterator,

Если вы хотите иметь возможность перебирать все объекты, вы можете добавить его в качестве прототипа Object:

Object.prototype[Symbol.iterator] = function*() { 
    for(p of Reflect.ownKeys(this)){ yield this[p]; }
}

Это позволит вам перебирать значения объекта с помощью цикла for..., например:

for(val of obj) { console.log('Value is:' + val ) }

Внимание: на момент написания этого ответа (июнь 2018 г.) все другие браузеры, кроме IE, поддерживают генераторы и for...of итерация через Symbol.iterator

Приведенные выше ответы немного раздражают, потому что они не объясняют, что вы делаете внутри цикла for после того, как убедитесь, что это объект: ВЫ НЕ ПОЛУЧАЕТЕ ЕГО ПРЯМО! На самом деле вы получили только КЛЮЧ, который вам нужен для подачи заявления в OBJ:

var obj = {
  a: "foo",
  b: "bar",
  c: "foobar"
};

// We need to iterate the string keys (not the objects)
for(var someKey in obj)
{
  // We check if this key exists in the obj
  if (obj.hasOwnProperty(someKey))
  {
    // someKey is only the KEY (string)! Use it to get the obj:
    var myActualPropFromObj = obj[someKey]; // Since dynamic, use [] since the key isn't literally named "someKey"

    // NOW you can treat it like an obj
    var shouldBeBar = myActualPropFromObj.b;
  }
}

Это все безопасно ECMA5. Даже работает в хромых версиях JS, таких как Rhino;)

Вы можете получить доступ к вложенным свойствам объекта, используя for...in и forEach петля.

for...in:

for (const key in info) {
    consoled.log(info[key]);
}

forEach:

Object.keys(info).forEach(function(prop) {
    console.log(info[prop]);
    // cities: Array[3], continent: "North America", images: Array[3], name: "Canada"
    // "prop" is the property name
    // "data[prop]" is the property value
});

Вы можете использовать Lodash. Документация

var obj = {a: 1, b: 2, c: 3};
_.keys(obj).forEach(function (key) {
    ...
});
Object.keys(obj).forEach(key =>
  console.log(`key=${key} value=${obj[key]}`)
);

В настоящее время вы можете преобразовать стандартный объект JS в итерируемый объект, просто добавив метод Symbol.iterator. Тогда вы можете использовать for of Цикл и принять его значения напрямую или даже может использовать оператор распространения на объекте тоже. Здорово. Давайте посмотрим, как мы можем это сделать:

var o = {a:1,b:2,c:3},
    a = [];
o[Symbol.iterator] = function*(){
                       var ok = Object.keys(this);
                            i = 0;
                       while (i < ok.length) yield this[ok[i++]];
                     };
for (var value of o) console.log(value);
// or you can even do like
a = [...o];
console.log(a);

Ваш for цикл перебирает все свойства объекта obj, propt определяется в первой строке вашего цикла for. Это строка, которая является именем свойства obj объект. На первой итерации цикла propt будет "имя".

Объекты в JavaScript являются коллекциями свойств и поэтому могут быть зациклены в каждом выражении.

Вы должны думать о obj в качестве коллекции значения ключа.

Если работает Node, я бы порекомендовал:

Object.keys(obj).forEach((key, index) => {
    console.log(key);
});

Хотя самый популярный ответ верен, вот альтернативный вариант использования, например, если вы выполняете итерацию по объекту и хотите в конце создать массив. Использовать.map вместо того forEach

const newObj = Object.keys(obj).map(el => {
    //ell will hold keys 
   // Getting the value of the keys should be as simple as obj[el]
})

Я хочу добавить к ответам выше, потому что у вас могут быть другие намерения от Javascript. Объект JSON и объект Javascript - это разные вещи, и вы можете захотеть пройтись по свойствам объекта JSON, используя решения, предложенные выше, а затем удивиться.

Предположим, что у вас есть объект JSON, такой как:

var example = {
    "prop1": "value1",
    "prop2": [ "value2_0", value2_1"],
    "prop3": {
         "prop3_1": "value3_1"
    }
}

Неправильный способ перебора его "свойств":

function recursivelyIterateProperties(jsonObject) {
    for (var prop in Object.keys(example)) {
        console.log(prop);
        recursivelyIterateProperties(jsonObject[prop]);
    }
}

Вы можете быть удивлены, увидев запись консоли 0, 1и т. д. при переборе свойств prop1 а также prop2 и из prop3_1, Эти объекты являются последовательностями, а индексы последовательности являются свойствами этого объекта в Javascript.

Лучший способ рекурсивно перебрать свойства объекта JSON - это сначала проверить, является ли этот объект последовательностью или нет:

function recursivelyIterateProperties(jsonObject) {
    for (var prop in Object.keys(example)) {
        console.log(prop);
        if (!(typeof(jsonObject[prop]) === 'string')
            && !(jsonObject[prop] instanceof Array)) {
                recursivelyIterateProperties(jsonObject[prop]);

            }

     }
}

Здесь я перебираю каждый узел и создаю значимые имена узлов. Если вы заметили, instanceOf Array и instanceOf Object в основном делают одно и то же (хотя в моем приложении я даю другую логику)

function iterate(obj,parent_node) {
    parent_node = parent_node || '';
    for (var property in obj) {
        if (obj.hasOwnProperty(property)) {
            var node = parent_node + "/" + property;
            if(obj[property] instanceof Array) {
                //console.log('array: ' + node + ":" + obj[property]);
                iterate(obj[property],node)
            } else if(obj[property] instanceof Object){
                //console.log('Object: ' + node + ":" + obj[property]);
                iterate(obj[property],node)
            }
            else {
                console.log(node + ":" + obj[property]);
            }
        }
    }
}

примечание - меня вдохновляет ответ Ондрея Свейдара. Но это решение имеет лучшую производительность и менее неоднозначно

Также добавляем рекурсивный способ:

function iterate(obj) {
    // watch for objects we've already iterated so we won't end in endless cycle
    // for cases like var foo = {}; foo.bar = foo; iterate(foo);
    var walked = [];
    var stack = [{obj: obj, stack: ''}];
    while(stack.length > 0)
    {
        var item = stack.pop();
        var obj = item.obj;
        for (var property in obj) {
            if (obj.hasOwnProperty(property)) {
                if (typeof obj[property] == "object") {
                  // check if we haven't iterated through the reference yet
                  var alreadyFound = false;
                  for(var i = 0; i < walked.length; i++)
                  {
                    if (walked[i] === obj[property])
                    {
                      alreadyFound = true;
                      break;
                    }
                  }
                  // new object reference
                  if (!alreadyFound)
                  {
                    walked.push(obj[property]);
                    stack.push({obj: obj[property], stack: item.stack + '.' + property});
                  }
                }
                else
                {
                    console.log(item.stack + '.' + property + "=" + obj[property]);
                }
            }
        }
    }
}

Использование:

iterate({ foo: "foo", bar: { foo: "foo"} }); 

По сути, вы хотите просмотреть каждое свойство объекта.

JSFiddle

var Dictionary = {
  If: {
    you: {
      can: '',
      make: ''
    },
    sense: ''
  },
  of: {
    the: {
      sentence: {
        it: '',
        worked: ''
      }
    }
  }
};

function Iterate(obj) {
  for (prop in obj) {
    if (obj.hasOwnProperty(prop) && isNaN(prop)) {
      console.log(prop + ': ' + obj[prop]);
      Iterate(obj[prop]);
    }
  }
}
Iterate(Dictionary);

Цикл for..in заключается в том, что он создает новую переменную (var someVariable) и затем сохраняет каждое свойство данного объекта в этой новой переменной (someVariable) по одному. Поэтому, если вы используете block {}, вы можете выполнить итерацию. Рассмотрим следующий пример.

var obj = {
     name:'raman',
     hobby:'coding',
     planet:'earth'
     };

for(var someVariable in obj) {
  //do nothing..
}

console.log(someVariable); // outputs planet

Тип проверки

Вы можете проверить, как propt представляет свойства объекта,

typeof propt

чтобы обнаружить, что это всего лишь строка (имя свойства). Он связан с каждым свойством объекта из-за того, как for-in js работает "встроенный" цикл.

var obj = {
    name: "Simon",
    age: "20",
    clothing: {
        style: "simple",
        hipster: false
    }
}

for(var propt in obj){
    console.log(typeof propt,  propt + ': ' + obj[propt]);
}

Проверьте эту ссылку, это поможет https://www.w3schools.com/jsref/tryit.asp?filename=tryjsref_state_forin

var person = {fname:"John", lname:"Doe", age:25}; 

  var text = "";
  var x;
  for (x in person) {
    text += person[x] + " "; // where x will be fname,lname,age
   }
Console.log(text);

Для дальнейшего уточнения принятого ответа стоит отметить, что если вы создаете экземпляр объекта с помощью var object = Object.create(null) затем object.hasOwnProperty(property) вызовет ошибку TypeError. Поэтому, чтобы быть в безопасности, вам нужно вызвать его из прототипа так:

for (var property in object) {
    if (Object.prototype.hasOwnProperty.call(object, property)) {
        // do stuff
    }
}
Другие вопросы по тегам