如果有一个JavaScript对象:
var objects={...};

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

评论

读者注意:不要错过非常有见地的第二个答案

如何列出JavaScript对象的属性的可能重复项

#1 楼

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

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


评论


请注意要继承的原型对象的属性。另请:hasOwnProperty()

–橄榄
2013年9月21日在11:18

如果您正在阅读此答案,则一定要阅读其他答案

– mgarciaisaia
2015年12月11日23:35

如果您正在阅读此答案,并且可能正在处理字符串,那么绝对应该在表面打孔javascript。

–user1228
16年1月28日在14:35

如果您阅读上述答案,并且想在脸上打JavaScript,请尝试lodash

–slugmandrew
19年2月19日在17:33

应该指出的是,这将不包括将其可枚举标志设置为false的属性。除其他事项外,这意味着您不会迭代任何类方法,但是会迭代以其他方式创建的方法。

–丰富的历史
19年7月28日在5:24

#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.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,该Object.values返回属性名称(包括不可枚举的属性)和符号的列表。

数组理解(请勿尝试使用)

在发布之前,已将数组理解从ECMAScript 6中删除。在删除它们之前,解决方案应该是这样的:

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

// use vals array


ECMAScript 2017+

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

const values = Object.values(obj);

// use values array or:

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


如果要同时使用键和值,那么[key, value]非常适合您。它产生一个充满for-of对的阵列。您可以按原样使用它,也可以在Object.values循环中使用(也请注意ECMAScript 2015的解构分配):

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



Object shim

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

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


现在可以像

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

如果要避免在存在本机q4312079q时发出匀光,则可以执行以下操作:

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


最后...

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

评论


这应该是被接受的(或至少被否决的)答案,因为被接受的答案是不完整的(@olive指出了这一点)。

– 0xc0de
2013年9月26日12:02



所有所谓的技巧,我们仍然需要两次提及obj,这真是可惜。我想创建一个辅助函数是不可避免的吗?类似于values(obj)。

–史蒂文·哈里安托(Steven Haryanto)
13年11月23日在9:16



这些方法中的任何一种都可以用作垫片。例如:Object.values = obj => Object.keys(obj).map(key => obj [key]);

– Qubyte
13年11月24日在2:43

ECMA 5解决方案应可在所有现代浏览器中使用。 ECMA 6尚未最终确定,并且所有浏览器都已初步提供支持。在Chrome中,部分实施了ECMA 6,但将其禁用。在Firefox中,支持更好,但是数组理解是错误的(如上所述)。我以为我使用将来时将暗示这一点。 @JacekLampart,哪个解决方案给您错误?

– Qubyte
13年12月1日在11:18



我无法想象为什么我们必须等待ES2017获得Object.values()方法。

–Herbertusz
16年3月13日在22:13

#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是常见的填充),您可能正在考虑修改Object原型。

–沙尘暴
13年5月21日在8:13



为什么需要使用hasOwnProperty()测试?在没有对象属性的对象的循环中如何迭代密钥?

– 1252748
2014年8月25日,1:16

Google @thomas,这很重要。它可能具有其原型链中的属性。

–乔
2014年11月19日17:59

#4 楼

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

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


评论


@MathieuAmiot-关心解释吗?

–加载
2014年2月7日下午13:55

lodash是下划线的一种api兼容替代,下划线是一种(较快的)下划线。

– Mathieu Amiot
2014年2月7日14:50

@Paden这是关于SO的一个相关问题:stackoverflow.com/questions/13789618/…

– jichi
2014年2月8日在0:04



lodash对此是不必要的,并且会膨胀您的代码库

– dman
18年4月17日在18:23

#5 楼

如果您真的想要一个值数组,那么我发现比使用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]);

对象o的键。在每次迭代中,k都设置为o的键。

#6 楼

ES5 Object.keys

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


评论


为什么这被否决了?我会说这是最干净的解决方案之一。

–塞巴斯蒂安·霍亚斯(Sebastian Hojas)
16年5月16日在11:04

我不知道,为什么这被否决。这是js中最简单,最纯净的解决方案,无需使用任何库或任何其他实用程序。

–sanjeev shetty
19年6月28日在9:23

#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()”。

– 0xc0de
2013年9月26日12:05

#8 楼

ECMA2017及更高版本:

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

https://developer.mozilla.org/zh-CN/docs/Web/JavaScript /参考/ Global_objects /对象/值

评论


应该注意,这不会返回继承的属性。

–丰富的历史
19年7月28日在5:26

#9 楼

这个问题并没有说明是否还需要继承和不可枚举的属性。
还有一个问题,就是要获取所有东西,继承的属性和非枚举的属性,这是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); 




#10 楼

对于CofeeScript时代的早期适应者来说,这是另一种等效方法。

val for key,val of objects


也许比这更好,因为objects可以简化为再次键入,然后可读性降低。

objects[key] for key of objects


#11 楼

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

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作为例子吗?谢谢。

– Chris22
19年3月14日在17:08

#12 楼

使用类似
的填充物:

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


然后使用

Object.values(my_object)


3)获利!

#13 楼

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

这将返回给定对象自己的可枚举属性值的数组。您将获得与使用for in循环相同的值,但没有原型上​​的属性。该示例可能会使情况更清晰:




 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 




#14 楼

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


#15 楼

这是类似于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上则不能。

– jaggedsoft
15年8月22日在23:07

#16 楼

即使某些浏览器尚不支持ES7,

既然,Object.values(<object>)将内置在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兼容,您将不会必须更改代码中的任何内容。

#17 楼

我知道我来晚了一点,但是这是新的Firefox 47 Object.values方法的补片

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


#18 楼

Object.entries以更好的方式做到这一点。




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




#19 楼

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

获取所有值:



最短方法:


const myValues = Object.values(myObj)


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


#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
2012年10月12日19:19

@zachelrath你是对的。 -但是,如果要获取值,此脚本很有用,因为当您知道键时,便可以使用object [key]在循环中获取值。

– fridojet
2012年11月14日15:07

@fridojet但这可以通过for..in(和hasOwnProperty)来完成,因此它实际上并没有获得任何收益。.我希望ECMAScript 5th定义Object.pairs(和Object.items为[[key,value],.. ]),但事实并非如此。

–user2246674
13年5月17日在6:01



#22 楼

现在,我使用Dojo工具包是因为较旧的浏览器不支持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']


评论


严格来说,数组是不正确的。您有一个字符串数组而不是数字数组。

– Qubyte
2014年3月23日22:21在

#23 楼

请使用

console.log(variable)


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

转到>>控制台