如何获取 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.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
垫片
最后,正如 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 => Object.keys(obj).map(key => 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 中最简单、最纯粹的解决方案,无需使用任何库或任何其他实用程序。 @sanjeevshettyObject.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 => 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(<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 兼容,您就无需更改代码中的任何内容。
【讨论】:
【参考方案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 对象的所有属性值(不知道键)?的主要内容,如果未能解决你的问题,请参考以下文章