Итерация через свойства объекта

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

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

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

+1864
источник поделиться
29 ответов

Для перебора свойств требуется дополнительная проверка hasOwnProperty:

for (var prop in obj) {
    if (Object.prototype.hasOwnProperty.call(obj, prop)) {
        // do stuff
    }
}

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

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


Также можно вызвать hasOwnProperty через сам объект:

if (obj.hasOwnProperty(prop)) {
    // do stuff
}

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

var obj = { foo: 42, hasOwnProperty: 'lol' };
obj.hasOwnProperty('foo');  // TypeError: hasOwnProperty is not a function

Вот почему безопаснее звонить через Object.prototype:

var obj = { foo: 42, hasOwnProperty: 'lol' };
Object.prototype.hasOwnProperty.call(obj, 'foo');  // true
+2339
источник

Начиная с 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)
  • Chrome: 5
  • Internet Explorer: 9

См. Ссылку на объект Mozilla Developer Network Object.keys() для дальнейшей информации.

+1056
источник
другие ответы

Связанные вопросы


Похожие вопросы

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

Object.keys(obj).forEach(e => console.log('key=${e}  value=${obj[e]}'));
+260
источник

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

Вы можете прочитать это как FOR каждое свойство IN объекта obj, присваивая каждому свойству переменную PROPT по очереди ".

+206
источник

В будущих версиях 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 => ...)
+108
источник

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

+37
источник

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

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

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

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

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

// This step is not necessary with Object.entries
if (object.hasOwnProperty(property)) {
  // do stuff
}
+24
источник
for (property in object) {
  ...
} 
+22
источник

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

$.each( obj, function( key, value ) {
  alert( key + ": " + value );
});
+21
источник

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

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

    // Do stuff...
}
+20
источник

Вышеприведенные ответы немного раздражают, потому что они не объясняют, что вы делаете внутри цикла 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;)

+18
источник

Чтобы добавить 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 попытается выполнить итерацию с использованием свойства iterator по умолчанию, которое должно быть определено как Symbol.iterator.

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

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

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

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

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

+15
источник

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

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

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

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

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

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

+11
источник
let obj = {"a": 3, "b": 2, "6": "a"}

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

// a
// 3
// 2
+11
источник

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

var obj = {a: 1, b: 2, c: 3};
_.keys(obj).forEach(function (key) {
    ...
});
+10
источник
Object.keys(obj).forEach(key =>
  console.log('key=${key} value=${obj[key]}')
);
+10
источник

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

+9
источник

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

Вы должны думать о obj как о наборе значений ключей.

+9
источник

В настоящее время вы можете преобразовать стандартный объект 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);
+9
источник

Типы способа итерации объекта в JavaScript

  • для... в цикле

  • для... из цикла

  • forEach() метод

  • map() метод

let obj = {
  city1: 'BOM',
  city2: 'BLR',
  city3: 'HYD',
  state: {
    city1: 'Sub-city1',
    city2: 'Sub-city2'
  }
}
console.log('----------------using for...in loop------')
for(let entry in obj) 
  console.log(entry +" -> "+ obj[entry])

for (var key in obj) {
    if (obj.hasOwnProperty(key)) {
        console.log(key + " -> " + obj[key]);
    }
}
console.log('----------------using for...of loop------')
for (const key of Object.keys(obj)) 
    console.log(key +" -> "+ obj[key]);

for (const [key, value] of Object.entries(obj)) 
    console.log(key +" -> "+ value);

console.log('----------------using forEach loop------')
Object.entries(obj).forEach(([key, value]) => console.log(key +" -> "+ value));
    
console.log('----------------using map function------')
Object.entries(obj).map(([k,v])=> console.log(k+' -> '+v))

Способ итерации вложенного объекта

let obj = {
  city1: 'ALD',
  city2: 'BLR',
  city3: 'HYD',
  state: {
    city4: 'Sub-city1',
    city5: 'Sub-city2'
  }
}
function nestedObj(obj) {
    for (let key in obj) {
        // checking if it nested to iterate again
        if (obj.hasOwnProperty(key) && 
           (typeof obj[key] === "object")) {
            nestedObj(obj[key])
        } else {
            // showing the flat attributes
            console.log(key + " -> " + obj[key]);
        }
    }
}
nestedObj(obj);

+6
источник

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

Object.keys(obj).forEach((key, index) => {
    console.log(key);
});
+5
источник

Хотя самый лучший ответ верен, здесь есть альтернативный вариант использования, т.е. если вы перебираете объект и хотите в конце создать массив. Используйте .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]
})
+5
источник

Также добавление рекурсивного способа:

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"} }); 
+4
источник

Здесь я повторяю каждый node и создаю значимые имена node. Если вы заметили, 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]);
            }
        }
    }
}

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

+3
источник

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

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);
+3
источник

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

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

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

console.log(someVariable); // outputs planet
+2
источник

Я хочу добавить к ответам выше, потому что у вас могут быть разные намерения от 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]);

            }

     }
}
+2
источник

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

for (var property in object) {
    if (Object.prototype.hasOwnProperty.call(object, property)) {
        // do stuff
    }
}
+1
источник

Вы можете использовать его для получения или установки значения объекта или массива с объектами. https://jsfiddle.net/narendra_globalsysinfo/yt97dbm5/

var reset = function(data){
                    for( var prop in data){
                        if(typeof data[prop] === 'object')
                        {
                            data[prop] = reset(data[prop]);
                        }
                        else{
                            if(typeof data[prop] !== 'function'){
                                var dataType = typeof data[prop];
                                var returnType = null;
                                switch(dataType){
                                    case 'number':
                                        returnType = 0;
                                        break;
                                    case 'string':
                                        returnType = '';
                                        break;
                                    case 'boolean':
                                        returnType = false;
                                        break;
                                    default:
                                        break;
                                }
                                data[prop] = returnType;
                            }

                        }
                    }
                    return data;

                }

var obj = { p1:{ p11:1,p12:'Hi'},p2:1,p3:function(){console.log('hi')} };
obj = reset(obj);

Он вернет тот же объект со значением, установленным по умолчанию

По умолчанию:  для int равно 0, для строки is '', а для boolean - false

Примечание: объект с функцией как свойство не будет reset, вы можете внести изменения в соответствии с требованиями и поблагодарить меня.

0

Посмотрите другие вопросы по меткам или Задайте вопрос