如果有一个Javascript对象:
var objects={...};
假设它有50多个属性,却不知道属性名称(即不知道“键”)如何在循环中获取每个属性值?
如果有一个Javascript对象:
var objects={...};
假设它有50多个属性,却不知道属性名称(即不知道“键”)如何在循环中获取每个属性值?
Answers:
通过使用一个简单的for..in
循环:
for(var key in objects) {
var value = objects[key];
}
enumerable
标志设置为false的属性。除其他事项外,这意味着您不会迭代任何类方法,但是会迭代以其他方式创建的方法。
根据您必须支持的浏览器,可以通过多种方式完成此操作。狂野的绝大多数浏览器都支持ECMAScript 5(ES5),但请注意,下面的许多示例都在使用Object.keys
,而IE <9中没有这些示例。请参阅兼容性表。
如果必须支持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及更高版本的浏览器中使用这些方法。它们从对象获取值,并避免枚举原型链。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可以更轻松地迭代数组。在循环中一个接一个地处理值时,可以利用它来发挥优势:
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
不能用于制作私有属性的原因)。Reflect
ECMAScript 2015 的新API提供了Reflect.ownKeys
,可返回属性名称(包括不可枚举的属性)和符号的列表。
在发布之前,已将数组理解从ECMAScript 6 中删除。在将其删除之前,解决方案应如下所示:
const vals = [for (key of Object.keys(obj)) obj[key]];
// use vals array
ECMAScript 2016添加了不影响该主题的功能。ECMAScript 2017规范增加了Object.values
和Object.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
匀场最后,如评论中所述,以及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,则可以访问此答案中的所有功能。
obj
两次,这是可耻的。我想创建一个辅助函数是不可避免的吗?类似于values(obj)。
Object.values = obj => Object.keys(obj).map(key => obj[key]);
这是一个可重用的函数,用于将值放入数组。它也考虑了原型。
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原型。
hasOwnProperty()
?在该对象没有属性的循环中如何迭代密钥?
如果你有机会到Underscore.js,您可以使用_.values
这样的功能:
_.values({one : 1, two : 2, three : 3}); // return [1, 2, 3]
ES5 Object.keys
var a = { a: 1, b: 2, c: 3 };
Object.keys(a).map(function(key){ return a[key] });
// result: [1,2,3]
您可以循环浏览以下按键:
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
ECMA2017起:
Object.values(obj)
将以数组的形式获取所有属性值。
https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_objects/Object/values
这个问题没有指定是否还需要继承和不可枚举的属性。
还有一个问题,要获取 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循环:
使用: 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
这是类似于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));
由于,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']
Object.entries以更好的方式做到这一点。
var dataObject = {"a":{"title":"shop"}, "b":{"title":"home"}}
Object.entries(dataObject).map(itemArray => {
console.log("key=", itemArray[0], "value=", itemArray[1])
})
const myObj = { a:1, b:2, c:3 }
获取所有值:
最短的方法:
const myValues = Object.values(myObj)
const myValues = Object.keys(myObj).map(key => myObj[key])
在ECMAScript5中使用
keys = Object.keys(object);
否则,如果您的浏览器不支持它,请使用众所周知的 for..in loop
for (key in object) {
// your code here
}
object[key]
来循环获取值。
for..in
(和hasOwnProperty)完成,所以它实际上并没有获得任何收益..我希望ECMAScript 5th可以定义Object.pairs
(并且Object.items
用于[[key, value], ..]
),但是可惜没有。
现在,我使用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']