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

三世轮回 提交于 2020-02-26 01:43:47

如果有一个Javascript对象:

var objects={...};

假设它具有50多个属性,却不知道属性名称(即不知道“键”)如何在循环中获取每个属性值?


#1楼

这是一个可重用的函数,用于将值放入数组。 它也考虑了原型。

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

#2楼

根据您必须支持的浏览器,可以通过多种方式完成此操作。 狂野的绝大多数浏览器都支持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
    }
}

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

Object.prototype.hasOwnProperty.call(obj, key) // ok

而不是

obj.hasOwnProperty(key) // bad

因为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
}

如果您想要一些更紧凑的东西,或者要谨慎使用循环中的函数,那么Array.prototype.forEach是您的朋友:

Object.keys(obj).forEach(function (key) {
    var val = obj[key];
    // use val
});

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

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

// use vals array

如果要使使用Object.keysnull安全(如for-in ),则可以执行Object.keys(obj || {})...

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

ECMAScript 2015+(又名ES6)

使用ECMAScript 2015可以更轻松地迭代数组。在循环中一个接一个地处理值时,可以利用它来发挥优势:

for (const key of Object.keys(obj)) {
    const val = obj[key];
    // use val
}

使用ECMAScript 2015胖箭头功能,将对象映射到值数组成为一种情况:

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

// use vals array

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

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

在发布之前, 已将数组理解从ECMAScript 6中删除 。 在将其删除之前,解决方案应如下所示:

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

// use vals array

ECMAScript 2017+

ECMAScript 2016添加了不影响该主题的功能。 ECMAScript 2017规范添加了Object.valuesObject.entries 。 两个都返回数组(考虑到与Array.entries的类比,这会使某些人感到惊讶)。 Object.values可以按Object.values使用,也可以与for-of循环一起使用。

const values = Object.values(obj);

// use values array or:

for (const val of Object.values(obj)) {
    // use val
}

如果要同时使用键和值,则Object.entries适合您。 它产生一个由[key, value]对填充的数组。 您可以按原样使用它,也可以在for-of循环中使用(也请注意ECMAScript 2015的解构分配):

for (const [key, val] of Object.entries(obj)) {
    // use key and val
}

Object.values填充

最后,如评论中所述,以及teh_senaus在另一个答案中指出,可能值得将其中之一用作垫片。 不用担心,以下内容不会更改原型,它只是向Object添加了一个方法(危险性要小得多)。 使用胖箭头功能,这也可以一行完成:

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

您现在可以像

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

如果要避免在存在本机Object.values时进行调整,则可以执行以下操作:

Object.values = Object.values || (obj => Object.keys(obj).map(key => obj[key]));

最后...

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


#3楼

var objects={...}; this.getAllvalues = function () {
        var vls = [];
        for (var key in objects) {
            vls.push(objects[key]);
        }
        return vls;
    }

#4楼

如果可以访问_.values ,则可以使用_.values函数,如下所示:

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

#5楼

现在,我使用Dojo Toolkit,因为较旧的浏览器不支持Object.values

require(['dojox/lang/functional/object'], function(Object) {
    var obj = { key1: '1', key2: '2', key3: '3' };
    var values = Object.values(obj);
    console.log(values);
});

输出:

['1', '2', '3']
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!