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

IT技术 javascript object properties iteration introspection
2021-03-14 23:05:23

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

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

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

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

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

就我而言,我特别考虑了一种情况,即函数需要接受一系列名称-值对,但属性的名称可能会发生变化。

到目前为止,我对如何做到这一点的想法是将属性的名称与数据一起传递给函数,但这感觉就像一个黑客。如果可能的话,我更愿意通过内省来做到这一点。

6个回答

你可以像这样循环键:

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
这是提出问题时的最佳答案,但我删除了复选标记,因为后来的 JS 版本提供了更好的工具。
2021-04-27 23:05:23
你是不是把最后一个弄出来然后真的侥幸逃脱了?干得好……=)
2021-04-29 23:05:23
顺便说一句,警报是一种错误的调试方式,请尝试 console.log
2021-04-30 23:05:23
这存在于 Firefox ( docs ) 中,但公平地说它不是通用的。我会更新答案以提及这一点。
2021-05-04 23:05:23

旧版本的 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']]
使用“名称”和“值”作为对象键会产生误导。此函数仅返回列表中的键,而不返回值。{ name1: 'value1', name2: 'value2' } 将避免初学者混淆。Object.keys(data); // ['name1', 'name2']
2021-04-16 23:05:23
@JamesNicholson 我同意,编辑后不那么令人困惑。
2021-04-30 23:05:23
现在这实际上回答了这个问题,做得好@Adam Lassek,做得非常好。
2021-05-12 23:05:23
for(var property in data) {
    alert(property);
}

您经常需要检查对象实例特定属性,而不是所有共享的原型方法和属性:

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

    return A.join(', ');
}
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]);
}