Как мне получить доступ к свойствам объекта javascript, если я не знаю имен?

124

Скажем, у вас есть такой объект javascript:

var data = { foo: 'bar', baz: 'quux' };

Вы можете получить доступ к свойствам по имени свойства:

var foo = data.foo;
var baz = data["baz"];

Но возможно ли получить эти значения, если вы не знаете названия свойств? Неужели неупорядоченность этих свойств делает невозможным их различение?

В моем случае я имею в виду конкретно ситуацию, когда функция должна принимать ряд пар имя-значение, но имена свойств могут измениться.

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

Адам Лассек
источник

Ответы:

144

Вы можете перемещаться по клавишам следующим образом:

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

Это регистрирует «Имя» и «Значение».

Если у вас есть более сложный тип объекта (а не просто простой хеш-подобный объект, как в исходном вопросе), вам нужно будет перебирать только ключи, принадлежащие самому объекту, а не ключи в прототипе объекта :

for (var key in data) {
  if (data.hasOwnProperty(key)) {
    console.log(key);
  }
}

Как вы заметили, не гарантируется, что ключи находятся в каком-либо определенном порядке. Обратите внимание, чем это отличается от следующего:

for each (var value in data) {
  console.log(value);
}

В этом примере выполняется цикл по значениям, поэтому он будет регистрировать Property Nameи 0. NB: for eachсинтаксис в основном поддерживается только в Firefox, но не в других браузерах.

Если ваши целевые браузеры поддерживают ES5 или ваш сайт включает es5-shim.js(рекомендуется), вы также можете использовать Object.keys:

var data = { Name: 'Property Name', Value: '0' };
console.log(Object.keys(data)); // => ["Name", "Value"]

и цикл с Array.prototype.forEach:

Object.keys(data).forEach(function (key) {
  console.log(data[key]);
});
// => Logs "Property Name", 0
Рон ДеВера
источник
Вы только что придумали последнее, и оно действительно сошло с рук? Молодец ... =)
nickl-
Это существует в Firefox ( документация ), но справедливо то, что это не универсально. Я обновлю ответ, чтобы упомянуть об этом.
Рон ДеВера
28
btw alert - плохой способ отлаживать вещи, попробуйте console.log
StackOverflowed
Это был лучший ответ, когда был задан вопрос, но я убираю галочку, потому что более поздние версии JS предоставляют лучшие инструменты.
Адам Лассек
65

Старые версии JavaScript (<ES5) требуют использования for..in цикла:

for (var key in data) {
  if (data.hasOwnProperty(key)) {
    // do something with key
  }
}

ES5 представляет Object.keys и Array # forEach, что немного упрощает задачу:

var data = { foo: 'bar', baz: 'quux' };

Object.keys(data); // ['foo', 'baz']
Object.keys(data).map(function(key){ return data[key] }) // ['bar', 'quux']
Object.keys(data).forEach(function (key) {
  // do something with data[key]
});

ES2017 представляет Object.valuesи Object.entries.

Object.values(data) // ['bar', 'quux']
Object.entries(data) // [['foo', 'bar'], ['baz', 'quux']]
Адам Лассек
источник
1
Теперь это действительно отвечает на вопрос, молодец @Adam Lassek, очень хорошо сделано.
nickl-
Использование в качестве ключей объекта и «имени», и «значения» вводит в заблуждение. Эта функция возвращает только ключи в списке, но не значения. {name1: 'value1', name2: 'value2'} позволит избежать путаницы для новичков. Object.keys (данные); // ['name1', 'name2']
Джеймс Николсон
2
@JamesNicholson Я согласен, отредактировано, чтобы было меньше путаницы.
Адам Лассек
4

Вам часто может понадобиться изучить конкретные свойства экземпляра объекта без использования всех общих методов и свойств прототипа:

 Obj.prototype.toString= function(){
        var A= [];
        for(var p in this){
            if(this.hasOwnProperty(p)){
                A[A.length]= p+'='+this[p];
            }
        }

    return A.join(', ');
}
Kennebec
источник
3
function getDetailedObject(inputObject) {
    var detailedObject = {}, properties;

    do {
        properties = Object.getOwnPropertyNames( inputObject );
        for (var o in properties) {
            detailedObject[properties[o]] = inputObject[properties[o]];
        }
    } while ( inputObject = Object.getPrototypeOf( inputObject ) );

    return detailedObject;
}

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

var obj = { 'b': '4' }; //example object
var detailedObject = getDetailedObject(obj);
for(var o in detailedObject) {
    console.log('key: ' + o + '   value: ' + detailedObject[o]);
}
Шишир Арора
источник
1
var obj = {
 a: [1, 3, 4],
 b: 2,
 c: ['hi', 'there']
 }
for(let r in obj){  //for in loop iterates all properties in an object
 console.log(r) ;  //print all properties in sequence
 console.log(obj[r]);//print all properties values
}
Mayank_VK
источник
где этот ответ предоставляет то, что требуется OP, но небольшое описание того, что вы делаете, и почему OP должен использовать это, было бы неплохо, также не забывайте .hasOwnProperty()при использовании for in для итерации объекта.
Мухаммад Омер Аслам
Спасибо, я согласен с тем, что .hasOwnProperty () выполняет итерацию по объекту, но выполняет итерацию для проверки условия, однако, используя его, мы не можем распечатать все свойства объекта. Поправьте меня, если ошибаюсь.
Mayank_VK
В hasOwnProperty()возвращает метод A , booleanуказывающий , имеет ли объект указанное свойство в качестве своего собственного имущества (в отличие от наследования его) . см. этот пример
Мухаммад Омер Аслам
1

Вы можете использовать Object.keys () , «который возвращает массив имен перечислимых свойств данного объекта в том же порядке, что и в обычном цикле».

Вы можете использовать любой объект вместо stats:

var stats = {
  a: 3,
  b: 6,
  d: 7,
  erijgolekngo: 35
}
/*  this is the answer here  */
for (var key in Object.keys(stats)) {
  var t = Object.keys(stats)[key];
  console.log(t + " value =: " + stats[t]);
}

Клоид Дж. Грин
источник
Не могли бы вы добавить больше объяснений?
Кейт Пинсон,
Object.keys( stats )[key]не имеет смысла, всегда будет undefined.
Адам Лассек
-2
var attr, object_information='';

for(attr in object){

      //Get names and values of propertys with style (name : value)
      object_information += attr + ' : ' + object[attr] + '\n'; 

   }


alert(object_information); //Show all Object
isaax2
источник
Это ничего не добавляет к принятому ответу и представляет информацию наименее полезным из возможных способов. И это не учитывает унаследованные свойства.
Адам Лассек