如果有一个 JavaScript 对象:
var objects={...};
假设,它有 50 多个属性,不知道属性名称(即不知道“键”)如何在循环中获取每个属性值?
如果有一个 JavaScript 对象:
var objects={...};
假设,它有 50 多个属性,不知道属性名称(即不知道“键”)如何在循环中获取每个属性值?
根据您必须支持的浏览器,这可以通过多种方式完成。绝大多数浏览器都支持 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
(危险性要小得多)。使用 fat-arrow 函数,这也可以在一行中完成:
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,那么您就可以访问此答案中的所有功能。
通过使用一个简单的for..in
循环:
for(var key in objects) {
var value = objects[key];
}
这是一个可重用的函数,用于将值放入数组中。它也考虑到原型。
Object.values = function (obj) {
var vals = [];
for( var key in obj ) {
if ( obj.hasOwnProperty(key) ) {
vals.push(obj[key]);
}
}
return vals;
}
如果您有权访问 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]