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

Posted

技术标签:

【中文标题】如何获取 JavaScript 对象的所有属性值(不知道键)?【英文标题】:How to get all properties values of a JavaScript Object (without knowing the keys)? 【发布时间】:2011-11-10 12:33:40 【问题描述】:

如果有 javascript 对象:

var objects=...;

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

【问题讨论】:

读者注意:不要错过非常有见地的second answer How to list the properties of a JavaScript object的可能重复 【参考方案1】:

根据您必须支持的浏览器,这可以通过多种方式完成。绝大多数浏览器都支持 ECMAScript 5 (ES5),但请注意,下面的许多示例使用 Object.keys,这在 IE compatibility table。

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.keys 的人对null 安全(就像for-in 一样),那么您可以使用Object.keys(obj || )...

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

ECMAScript 2015+(A.K.A. ES6)

使用 ECMAScript 2015 更容易迭代数组。在循环中逐个处理值时,您可以利用这一点:

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

使用 ECMAScript 2015 fat-arrow 函数,将对象映射到值数组变得单行:

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 可以按原样使用,也可以与for-of 循环一起使用。

const values = Object.values(obj);

// use values array or:

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

如果您想同时使用键和值,那么Object.entries 适合您。它生成一个填充有[key, value] 对的数组。您可以按原样使用它,或者(另请注意 ECMAScript 2015 解构赋值)在 for-of 循环中使用:

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

Object.values垫片

最后,正如 cmets 和 teh_senaus 在另一个答案中所指出的那样,将其中一个用作 shim 可能是值得的。不用担心,以下并没有改变原型,只是在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]));

终于...

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

【讨论】:

这应该是被接受的(或至少更多赞成的)答案,因为接受的答案是不完整的(@olive 指出了这一点)。 遗憾的是,在所有所谓的花招中,我们仍然需要提到两次obj。我想创建一个辅助函数是不可避免的吗?像值(obj)这样的东西。 这些方法中的任何一种都可以用作垫片。例如:Object.values = obj =&gt; Object.keys(obj).map(key =&gt; obj[key]); ECMA 5 解决方案应该适用于所有现代浏览器。 ECMA 6 尚未最终确定,所有浏览器的支持都是初步的。在 Chrome 中,ECMA 6 部分实现但被禁用。在 Firefox 中,支持更好,但数组理解错误(如前所述)。我认为我使用将来时会暗示这一点。 @JacekLampart,哪个解决方案给了你错误? 我无法想象为什么我们必须等待 ES2017 才能获得 Object.values() 方法。【参考方案2】:

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

for(var key in objects) 
    var value = objects[key];

【讨论】:

小心被继承的原型对象的属性。参见:hasOwnProperty() 如果您正在阅读此答案,您应该肯定阅读the other one 如果您正在阅读此答案并且您可能正在处理字符串,那么您绝对应该在脸上打 javascript。 如果您阅读了上述答案并想打JavaScript,请尝试lodash 应该指出,这将不包括将enumerable 标志设置为 false 的属性。这 - 除其他外 - 意味着您不会迭代任何类方法,但您将迭代以其他方式创建的方法。【参考方案3】:

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

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

【讨论】:

修改 Object 不是什么大问题(Object.keys 是一个常见的 shim),您可能正在考虑修改 Object 原型。 为什么需要使用hasOwnProperty() 进行测试?没有该属性的对象的循环中如何迭代键? 谷歌@thomas,这很重要。它可能具有原型链中的属性。【参考方案4】:

如果你可以访问 Underscore.js,你可以像这样使用_.values 函数:

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

【讨论】:

@MathieuAmiot -- 需要解释一下吗? lodash 是一种与 api 兼容的下划线替代品,一种(方式)更快的替代品。 @Paden 这是关于 SO 的相关问题:***.com/questions/13789618/… lodash 对此是不必要的,它会使你的代码库膨胀【参考方案5】:

ES5 Object.keys

var a =  a: 1, b: 2, c: 3 ;
Object.keys(a).map(function(key) return a[key] );
// result: [1,2,3]

【讨论】:

为什么这被否决了?我会说这是最干净的解决方案之一。 我不知道,为什么这被否决了。这是 js 中最简单、最纯粹的解决方案,无需使用任何库或任何其他实用程序。 @sanjeevshetty Object.values 是更简单的解决方案。【参考方案6】:

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

ECMA 5.1+

function values(o)  return Object.keys(o).map(function(k)return o[k]) 

值得注意的是,在大多数情况下,您并不真的需要一个值数组,这样做会更快:

for(var k in o) something(o[k]);

这会遍历 Object o 的键。在每次迭代中,将 k 设置为 o 的键。

【讨论】:

【参考方案7】:

你可以遍历键:

foo = one:1, two:2, three:3;
for (key in foo)
    console.log("foo["+ key +"]="+ foo[key]);

将输出:

foo[one]=1
foo[two]=2
foo[three]=3

【讨论】:

如果要避免继承属性,还需要检查`hasOwnProperty()'。【参考方案8】:

ECMA2017 起:

Object.values(obj) 会将所有属性值作为数组获取。

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

【讨论】:

应该注意这不会返回继承的属性。【参考方案9】:

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

获取所有值:

最短路径:

const myValues = Object.values(myObj)

const myValues = Object.keys(myObj).map(key =&gt; myObj[key])

【讨论】:

谢谢,这很好用。【参考方案10】:

问题没有说明是否还需要继承和不可枚举的属性。

有a question for getting everything, inherited properties and non-enumerable properties also,Google 无法轻易找到。

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

function getAllPropertyNames(obj) 
    let result = new Set();
    while (obj) 
        Object.getOwnPropertyNames(obj).forEach(p => result.add(p));
        obj = Object.getPrototypeOf(obj);
    
    return [...result];

然后遍历它们,只需使用 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];


let obj = 
  abc: 123,
  xyz: 1.234,
  foobar: "hello"
;

for (p of getAllPropertyNames(obj)) console.log(p);

【讨论】:

【参考方案11】:

对于那些在 CofeeScript 时代早期适应的人,这里有另一个等价物。

val for key,val of objects

这可能比这更好,因为objects 可以简化为再次键入并降低可读性。

objects[key] for key of objects

【讨论】:

【参考方案12】:

显然 - 正如我最近了解到的 - 这是最快的方法:

var objs = ...;
var objKeys = Object.keys(obj);
for (var i = 0, objLen = objKeys.length; i < objLen; i++) 
    // do whatever in here
    var obj = objs[objKeys[i]];

【讨论】:

你能放一个codepen或jsfiddle这个例子吗?谢谢。【参考方案13】:

使用以下 polyfill:

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

然后使用

Object.values(my_object)

3) 利润!

【讨论】:

【参考方案14】:

我意识到我来晚了,但这里有一个 shim 用于新的 firefox 47 Object.values 方法

Object.prototype.values = Object.prototype.values || function(obj) 
  return this.keys(obj).map(function(key)
    return obj[key];
  );
;

【讨论】:

【参考方案15】:

Object.entries 做得更好。

  var dataObject = "a":"title":"shop", "b":"title":"home"
 
   Object.entries(dataObject).map(itemArray =>  
     console.log("key=", itemArray[0], "value=", itemArray[1])
  )

【讨论】:

【参考方案16】:

使用:Object.values(),我们传入一个对象作为参数,并接收一个值数组作为返回值。

这将返回给定对象自己的可枚举属性值的数组。您将获得与使用 for in 循环相同的值,但没有 Prototype 上的属性。这个例子可能会让事情更清楚:

function person (name) 
  this.name = name;


person.prototype.age = 5;

let dude = new person('dude');

for(let prop in dude) 
  console.log(dude[prop]);     // for in still shows age because this is on the prototype
                              // we can use hasOwnProperty but this is not very elegant

// ES6 + 
console.log(Object.values(dude));
// very concise and we don't show props on prototype

【讨论】:

【参考方案17】:
const object1 = 
  a: 'somestring',
  b: 42
;

for (let [key, value] of Object.entries(object1)) 
  console.log(`$key: $value`);


// expected output:
// "a: somestring"
// "b: 42"
// order is not guaranteed

【讨论】:

【参考方案18】:

这里有个类似php的array_values()的函数

function array_values(input) 
  var output = [], key = '';
  for ( key in input )  output[output.length] = input[key]; 
  return output;

如果您使用的是 ES6 或更高版本,以下是获取对象值的方法:

Array.from(values(obj));

【讨论】:

由于某些原因 values() 在 Chrome 和 Firefox 中有效,但在 iojs/node 上无效。【参考方案19】:

兼容 ES7,部分浏览器还不支持

因为,Object.values(&lt;object&gt;) 将被内置在 ES7 &

在等待所有浏览器支持它之前,您可以将它包装在一个函数中:

Object.vals=(o)=>(Object.values)?Object.values(o):Object.keys(o).map((k)=>o[k])

然后:

Object.vals(lastname:'T',firstname:'A')
 // ['T','A']

一旦浏览器与 ES7 兼容,您就无需更改代码中的任何内容。

【讨论】:

【参考方案20】:
var objects=...; this.getAllvalues = function () 
        var vls = [];
        for (var key in objects) 
            vls.push(objects[key]);
        
        return vls;
    

【讨论】:

【参考方案21】:

ECMAScript5中使用

 keys = Object.keys(object);

否则如果您的浏览器不支持,请使用众所周知的for..in loop

for (key in object) 
    // your code here

【讨论】:

问题是要求值,而不是键。 @zachelrath 你是对的。 - 但是,如果您想获取值,此脚本很有用,因为当您知道键时,您可以使用 object[key] 在循环中获取值。 @fridojet 但这可以用for..in(和hasOwnProperty)来完成,所以它并没有真正获得任何东西..我希望ECMAScript 5th定义Object.pairs(和Object.items为@987654328 @),但可惜不是。【参考方案22】:

现在我使用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']

【讨论】:

严格来说,数组是不正确的。你有一个字符串数组而不是一个数字数组。【参考方案23】:

使用

console.log(variable)

如果您使用 google chrome 打开控制台,请使用 Ctrl+Shift+j

转到 >> 控制台

【讨论】:

以上是关于如何获取 JavaScript 对象的所有属性值(不知道键)?的主要内容,如果未能解决你的问题,请参考以下文章

如何通过Javascript中的属性值获取另一个对象内的对象值

javascript获取对象直接量中的属性和属性值

如何获取对象的所有属性?

如何通过值获取 JavaScript 对象中的键?

JavaScript中DOM操作之设定标签属性

如何查看javascript object对象的所拥有的属性值