如何获取Javascript对象的所有属性值(不知道密钥)?

Mel*_*lon 439 javascript javascript-objects

如果有Javascript对象:

var objects={...};
Run Code Online (Sandbox Code Playgroud)

假设,它有超过50个属性,不知道属性名称(不知道'键')如何在循环中获取每个属性值?

qub*_*yte 980

根据您必须支持的浏览器,可以通过多种方式完成此操作.绝大多数浏览器都支持ECMAScript 5(ES5),但要注意下面的许多示例都使用Object.keys,这在IE <9中不可用.请参阅兼容性表.

ECMAScript 3+

如果您必须支持旧版本的IE,那么这是您的选择:

for (var key in obj) {
    if (Object.prototype.hasOwnProperty.call(obj, key)) {
        var val = obj[key];
        // use val
    }
}
Run Code Online (Sandbox Code Playgroud)

嵌套if确保您不会枚举对象原型链中的属性(这是您几乎肯定想要的行为).你必须使用

Object.prototype.hasOwnProperty.call(obj, key) // ok
Run Code Online (Sandbox Code Playgroud)

而不是

obj.hasOwnProperty(key) // bad
Run Code Online (Sandbox Code Playgroud)

因为ECMAScript 5+允许您使用创建无原型对象Object.create(null),并且这些对象将不具有该hasOwnProperty方法.顽皮的代码也可能产生覆盖该hasOwnProperty方法的对象.

ECMAScript 5+

您可以在任何支持ECMAScript 5及更高版本的浏览器中使用这些方法.这些从对象获取值并避免枚举原型链.obj你的对象在哪里:

var keys = Object.keys(obj);

for (var i = 0; i < keys.length; i++) {
    var val = obj[keys[i]];
    // use val
}
Run Code Online (Sandbox Code Playgroud)

如果你想要一些更紧凑的东西,或者你想要小心循环中的函数,那么Array.prototype.forEach你的朋友是:

Object.keys(obj).forEach(function (key) {
    var val = obj[key];
    // use val
});
Run Code Online (Sandbox Code Playgroud)

下一个方法构建一个包含对象值的数组.这很方便循环.

var vals = Object.keys(obj).map(function (key) {
    return obj[key];
});

// use vals array
Run Code Online (Sandbox Code Playgroud)

如果你想使那些使用Object.keys安全的null(按原样for-in),那么你可以做Object.keys(obj || {})....

Object.keys返回可枚举的属性.对于迭代简单对象,这通常就足够了.如果您有需要使用的不可枚举属性的东西,您可以使用Object.getOwnPropertyNames它代替Object.keys.

ECMAScript 2015+(AKA ES6)

使用ECMAScript 2015可以更容易地迭代数组.在循环中逐个处理值时,可以使用此优势:

for (const key of Object.keys(obj)) {
    const val = obj[key];
    // use val
}
Run Code Online (Sandbox Code Playgroud)

使用ECMAScript 2015 fat-arrow函数,将对象映射到值数组成为一个单行:

const vals = Object.keys(obj).map(key => obj[key]);

// use vals array
Run Code Online (Sandbox Code Playgroud)

ECMAScript 2015介绍Symbol了其中的实例可以用作属性名称.要获取要枚举的对象的符号,请使用Object.getOwnPropertySymbols(此函数是Symbol 不能用于创建私有属性的原因).Reflect来自ECMAScript 2015 的新API提供了Reflect.ownKeys返回属性名称(包括不可枚举的)和符号的列表.

数组理解(不要尝试使用)

在发布之前,已从 ECMAScript 6 中删除了数组解析.在删除之前,解决方案看起来像:

const vals = [for (key of Object.keys(obj)) obj[key]];

// use vals array
Run Code Online (Sandbox Code Playgroud)

ECMAScript 2017+

ECMAScript 2016添加了不影响此主题的功能.ECMAScript 2017规范增加了Object.valuesObject.entries.两个返回数组(对于某些类比而言,这将是令人惊讶的Array.entries).Object.values可以按原样使用,也可以for-of循环使用.

const values = Object.values(obj);

// use values array or:

for (const val of Object.values(obj)) {
    // use val
}
Run Code Online (Sandbox Code Playgroud)

如果你想同时使用键和值,那么Object.entries适合你.它产生一个充满[key, value]对的数组.您可以在for-of循环中使用它,或者(请注意ECMAScript 2015解构分配):

for (const [key, val] of Object.entries(obj)) {
    // use key and val
}
Run Code Online (Sandbox Code Playgroud)

Object.values 垫片

最后,正如评论和teh_senaus在另一个答案中所指出的那样,使用其中一个作为垫片可能是值得的.别担心,以下内容并没有改变原型,它只是添加了一种方法Object(危险性要小得多).使用fat-arrow函数,也可以在一行中完成:

Object.values = obj => Object.keys(obj).map(key => obj[key]);
Run Code Online (Sandbox Code Playgroud)

你现在可以使用它

// ['one', 'two', 'three']
var values = Object.values({ a: 'one', b: 'two', c: 'three' });
Run Code Online (Sandbox Code Playgroud)

如果您想在本机Object.values存在时避免填充,则可以执行以下操作:

Object.values = Object.values || (obj => Object.keys(obj).map(key => obj[key]));
Run Code Online (Sandbox Code Playgroud)

最后...

请注意您需要支持的浏览器/版本.在实现方法或语言功能的地方,上述内容是正确的.例如,默认情况下,在V8中默认关闭对ECMAScript 2015的支持,直到最近才支持Chrome浏览器.在您打算支持的浏览器实现您需要的功能之前,应避免使用ECMAScript 2015中的功能.如果您使用babel将代码编译为ECMAScript 5,那么您可以访问此答案中的所有功能.

  • 这应该是被接受的(或至少更加赞成的)答案,因为被接受的答案是不完整的(@olive指出这一点). (9认同)
  • 我无法想象为什么我们必须等待ES2017获取Object.values()方法. (2认同)

Tat*_*nen 430

通过使用一个简单的for..in循环:

for(var key in objects) {
    var value = objects[key];
}
Run Code Online (Sandbox Code Playgroud)

  • **如果你正在阅读这个答案,你应该_definitely_阅读[另一个](http://stackoverflow.com/a/16643074/641451)** (96认同)
  • 注意要继承的原型对象的属性.请参阅:hasOwnProperty() (90认同)
  • 如果你正在阅读这个答案而你可能正在处理字符串,那么你肯定应该使用javascript. (17认同)

teh*_*aus 31

这是一个可重用的函数,用于将值转换为数组.它也需要考虑原型.

Object.values = function (obj) {
    var vals = [];
    for( var key in obj ) {
        if ( obj.hasOwnProperty(key) ) {
            vals.push(obj[key]);
        }
    }
    return vals;
}
Run Code Online (Sandbox Code Playgroud)

  • 修改`Object`并不是一个大问题('Object.keys`是一个常见的垫片),你可能正在考虑修改Object原型. (15认同)
  • 谷歌@thomas,这很重要.它可能具有其原型链的属性. (4认同)

jic*_*chi 28

如果您可以访问Underscore.js,则可以使用如下_.values函数:

_.values({one : 1, two : 2, three : 3}); // return [1, 2, 3]
Run Code Online (Sandbox Code Playgroud)

  • lodash对此没有必要,并且会使你的代码库膨胀 (2认同)

zzz*_*zzz 14

如果你真的想要一个值数组,我发现这比使用for ... in循环构建一个数组更干净.

ECMA 5.1+

function values(o) { return Object.keys(o).map(function(k){return o[k]}) }
Run Code Online (Sandbox Code Playgroud)

值得注意的是,在大多数情况下,您并不真正需要一组值,执行此操作会更快:

for(var k in o) something(o[k]);
Run Code Online (Sandbox Code Playgroud)

这将迭代Object o的键.在每次迭代中,k被设置为o的键.


小智 9

ES5 Object.keys

var a = { a: 1, b: 2, c: 3 };
Object.keys(a).map(function(key){ return a[key] });
// result: [1,2,3]
Run Code Online (Sandbox Code Playgroud)

  • 为什么这被贬低了?我想说这是最干净的解决方案之一. (3认同)

小智 9

const myObj = { a:1, b:2, c:3 }

获取所有值:

  • 最短路线:

    • const myValues = Object.values(myObj)
  • const myValues = Object.keys(myObj).map(key => myObj[key])


ari*_*era 5

你可以循环键:

foo = {one:1, two:2, three:3};
for (key in foo){
    console.log("foo["+ key +"]="+ foo[key]);
}
Run Code Online (Sandbox Code Playgroud)

将输出:

foo[one]=1
foo[two]=2
foo[three]=3
Run Code Online (Sandbox Code Playgroud)

  • 如果要避免继承属性,还需要检查`hasOwnProperty()'. (2认同)

ish*_*007 5

ECMA2017 起:

Object.values(obj) 将以数组的形式获取所有属性值。

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_objects/Object/values


nop*_*ole 5

该问题没有指定是否也需要继承和不可枚举的属性。

存在一个问题,即获取 Google 无法轻松找到的所有内容,包括继承属性和不可枚举属性。

如果我们要获取所有继承的和不可枚举的属性,我的解决方案是:

function getAllPropertyNames(obj) {
    let result = new Set();
    while (obj) {
        Object.getOwnPropertyNames(obj).forEach(p => result.add(p));
        obj = Object.getPrototypeOf(obj);
    }
    return [...result];
}
Run Code Online (Sandbox Code Playgroud)

然后迭代它们,只需使用 for-of 循​​环:

function getAllPropertyNames(obj) {
    let result = new Set();
    while (obj) {
        Object.getOwnPropertyNames(obj).forEach(p => result.add(p));
        obj = Object.getPrototypeOf(obj);
    }
    return [...result];
}
Run Code Online (Sandbox Code Playgroud)