如果我不知道名称,该如何访问javascript对象的属性?


124

假设您有一个像这样的javascript对象:

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

您可以通过属性名称访问属性:

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

但是,如果您不知道属性名称,是否可以获取这些值?这些属性的无序性质是否使其无法区分?

在我的情况下,我专门考虑一种情况,即一个函数需要接受一系列名称-值对,但是属性的名称可能会改变。

到目前为止,我对如何执行此操作的想法是将属性的名称与数据一起传递给函数,但这听起来像是一种hack。如果可能的话,我宁愿自省。

Answers:


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 Name0。注意: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

您是否刚刚制作了最后一个并真正摆脱了它?做得好... =)
尼克

它存在于Firefox(docs)中,但很明显,它不是通用的。我将更新答案以提及这一点。
罗恩·德维拉

28
btw警报是调试问题的一种坏方法,请尝试console.log
StackOverflowed 2012年

当问这个问题时,这是最好的答案,但是我删除了对号,因为以后的JS版本提供了更好的工具。
亚当·拉瑟克

65

旧版本的JavaScript(<ES5)需要使用for..in循环:

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

ES5引入了Object.keysArray#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.valuesObject.entries

Object.values(data) // ['bar', 'quux']
Object.entries(data) // [['foo', 'bar'], ['baz', 'quux']]

1
现在,这实际上回答了这个问题,@ Adam Lassek做得很好,做得很好。
nickl- 2012年

同时使用“名称”和“值”作为对象键是一种误导。此函数仅返回列表中的键,而不返回值。{name1:'value1',name2:'value2'}将避免初学者感到困惑。Object.keys(数据); // ['name1','name2']
James Nicholson

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(', ');
}

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
}

该答案提供了OP所需的内容,但简要说明了您在做什么以及OP应该使用它的原因,这也很好,也不要忘记.hasOwnProperty()在for中使用对象进行迭代。
穆罕默德·奥默·阿斯兰

谢谢,我同意.hasOwnProperty()会迭代对象,但是会迭代检查条件,但是使用它我们无法打印对象的所有属性。如果错了,请纠正我。
Mayank_VK'1

hasOwnProperty()方法返回一个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]);
}


您可以添加更多说明吗?
Keith Pinson

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

这不会为接受的答案增加任何内容,并以最不实用的方式显示信息。并且它不考虑继承的属性。
亚当·拉瑟克
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.