如何循环或枚举 JavaScript 对象?
我有一个如下所示的 JavaScript 对象:
var p = {
"p1": "value1",
"p2": "value2",
"p3": "value3"
};
如何循环遍历所有 p
的元素(p1
、p2
、p3
...) 并获取它们的键和值?
I have a JavaScript object like the following:
var p = {
"p1": "value1",
"p2": "value2",
"p3": "value3"
};
How do I loop through all of p
's elements (p1
, p2
, p3
...) and get their keys and values?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(30)
在
Object.keys()
上使用for-of
,例如:
Using a
for-of
onObject.keys()
Like:
您还可以使用 Object.keys() 并迭代对象键,如下所示以获取值:
You can also use Object.keys() and iterate over the object keys like below to get the value:
因此,通过使用 hasOwnProperty 测试每个对象键,它会给出与您想要的相同的键列表。 您不需要额外的测试操作,并且
Object.keys( obj ).forEach(function( key ){})
应该更快。 我们来证明一下:在我的 Firefox 中,我得到以下结果
附言。 在 Chrome 上,差异甚至更大 http://codepen.io/dsheiko/pen/JdrqXa
PS2:在 ES6 (EcmaScript 2015) 中,你可以更好地迭代可迭代对象:
So it gives the same list of keys as you intend by testing each object key with hasOwnProperty. You don't need that extra test operation than and
Object.keys( obj ).forEach(function( key ){})
is supposed to be faster. Let's prove it:In my Firefox I have following results
PS. on Chrome the difference even bigger http://codepen.io/dsheiko/pen/JdrqXa
PS2: In ES6 (EcmaScript 2015) you can iterate iterable object nicer:
在最新的 ES 脚本中,你可以这样做:
In latest ES script, you can do something like this:
将您的对象传递给
Object.keys()
。 这将返回一个包含对象中所有键的数组。 然后,您可以使用map
循环遍历数组。 使用 obj[key] ,其中 obj 是您的对象,key 是映射迭代中的当前值,您可以获取该键的值/财产。Pass your object to
Object.keys()
. This will return an array containing all the keys in the object. You can then loop through the array usingmap
. Usingobj[key]
whereobj
is your object andkey
is the current value in the map iteration, you can get the value for that key/property.只有没有依赖关系的 JavaScript 代码:
Only JavaScript code without dependencies:
Object.keys()
方法返回给定对象自己的可枚举属性的数组。 此处了解更多相关信息The
Object.keys()
method returns an array of a given object's own enumerable properties. Read more about it here这是迭代对象的另一种方法。
Here is another method to iterate through an object.
在 javascript 中迭代对象的多种方式
使用 for...in 循环
使用 for...of 循环
将 forEach() 与 Object.keys、Object.values、Object.entries
Multiple way to iterate object in javascript
Using for...in loop
Using for...of loop
Using forEach() with Object.keys, Object.values, Object.entries
使用纯 JavaScript 时,循环可能非常有趣。 似乎只有 ECMA6(新的 2015 JavaScript 规范)才能控制循环。 不幸的是,在我撰写本文时,浏览器和流行的集成开发环境 (IDE) 仍在努力支持完全新的功能。
乍一看,ECMA6 之前的 JavaScript 对象循环是什么样子的:
另外,我知道这超出了这个问题的范围,但在 2011 年,ECMAScript 5.1 仅为数组添加了
forEach
方法,该方法基本上创建了一种新的改进方法,可以循环遍历数组,同时仍然保留不可迭代对象与旧的冗长且令人困惑的for
循环。 但奇怪的是,这个新的forEach
方法不支持break
,这导致了各种其他问题。基本上在 2011 年,除了许多流行的库(jQuery、Underscore 等)决定重新实现之外,没有真正可靠的 JavaScript 循环方法。
截至 2015 年,我们现在拥有更好的开箱即用方式来循环(和中断)任何对象类型(包括数组和字符串)。 当建议成为主流时,JavaScript 中的循环最终将如下所示:
请注意,截至 2016 年 6 月 18 日,大多数浏览器将不支持上述代码。即使在 Chrome 中,您也需要启用此特殊标志才能使其工作:< code>chrome://flags/#enable-javascript-harmony
在这成为新标准之前,旧方法仍然可以使用,但流行库中也有替代方法,甚至 轻量级替代方案,适合那些不使用任何这些库的人。
Loops can be pretty interesting when using pure JavaScript. It seems that only ECMA6 (New 2015 JavaScript specification) got the loops under control. Unfortunately as I'm writing this, both Browsers and popular Integrated development environment (IDE) are still struggling to support completely the new bells and whistles.
At a glance here is what a JavaScript object loop look like before ECMA6:
Also, I know this is out of scope with this question but in 2011, ECMAScript 5.1 added the
forEach
method for Arrays only which basically created a new improved way to loop through arrays while still leaving non iterable objects with the old verbose and confusingfor
loop. But the odd part is that this newforEach
method does not supportbreak
which led to all sorts of other problems.Basically in 2011, there is not a real solid way to loop in JavaScript other than what many popular libraries (jQuery, Underscore, etc.) decided to re-implement.
As of 2015, we now have a better out of the box way to loop (and break) any object type (including Arrays and Strings). Here is what a loop in JavaScript will eventually look like when the recommendation becomes mainstream:
Note that most browsers won't support the code above as of June 18th 2016. Even in Chrome you need to enable this special flag for it to work:
chrome://flags/#enable-javascript-harmony
Until this becomes the new standard, the old method can still be used but there are also alternatives in popular libraries or even lightweight alternatives for those who aren't using any of these libraries.
你可以这样尝试。
myObject
将是{name: "", Phone: ""}
如此这般,这将生成键和值。 所以这里的键是name
,phone
,值就像dog
,123123
。示例
{name: "dog"}
这里的键是
name
,值是dog
。You can try like this.
myObject
will be{name: "", phone: ""}
so and so, this will generate key and value. So key here isname
,phone
and value are likedog
,123123
.Example
{name: "dog"}
Here key is
name
and value isdog
.您可以向所有对象添加一个简单的forEach函数,这样您就可以自动循环遍历任何对象:
对于那些不喜欢“for ... in”的人-method:
现在,您可以简单地调用:
如果您不想与其他 forEach-Methods 发生冲突,您可以使用您唯一的名称来命名它。
You can add a simple forEach function to all objects, so you can automatically loop through any object:
For those people who don't like the "for ... in"-method:
Now, you can simple call:
If you don't want to get conflicts with other forEach-Methods you can name it with your unique name.
循环可枚举 JavaScript 对象的一个好方法是使用
Object.keys
或Object.entries
并使用map 功能。 如下所示:
用于循环并在
ReactJS
上显示一些 UI,如下所示:实际上,我使用解构赋值两次,一次用于获取
key
一次用于获取name< /code> 和
价格
。A good way for looping on an enumerable JavaScript object which could be awesome and common for ReactJS is using
Object.keys
orObject.entries
with usingmap
function. like below:For looping and show some UI on
ReactJS
act like below:Actually, I use the destructuring assignment twice, once for getting
key
once for gettingname
andprice
.在 ES6 中,我们有众所周知的符号来公开一些以前的内部方法,您可以使用它来定义迭代器如何为此对象工作:
这将给出与在 es6 循环中使用 for... 相同的结果。
但了解您现在使用 es6 拥有的功能很重要!
In ES6 we have well-known symbols to expose some previously internal methods, you can use it to define how iterators work for this object:
this will give the same result as using for...in es6 loop.
But its important to know the capabilities you now have using es6!
我会这样做,而不是在每个
for ... in
循环中检查obj.hasOwnerProperty
。I would do this rather than checking
obj.hasOwnerProperty
within everyfor ... in
loop.您可以使用
for- in
循环,如其他人所示。 但是,您还必须确保您获得的密钥是对象的实际属性,而不是来自原型。这是片段:
For-of 与 Object.keys() 替代方案:
请注意
for- 的使用
而不是for-in
,如果不使用,它将在命名属性上返回未定义,并且Object.keys()
确保仅使用对象自己的属性,而不使用整个原型链属性使用新的
对象。 Entry()
方法:注意: Internet Explorer 本身不支持此方法。 您可以考虑为旧版浏览器使用 Polyfill。
You can use the
for-in
loop as shown by others. However, you also have to make sure that the key you get is an actual property of an object, and doesn't come from the prototype.Here is the snippet:
For-of with Object.keys() alternative:
Notice the use of
for-of
instead offor-in
, if not used it will return undefined on named properties, andObject.keys()
ensures the use of only the object's own properties without the whole prototype-chain propertiesUsing the new
Object.entries()
method:Note: This method is not supported natively by Internet Explorer. You may consider using a Polyfill for older browsers.
在 ECMAScript 5 下,您可以组合
Object .keys()
和Array.prototype.forEach()
:ECMAScript 6 添加了
for...of
:ECMAScript 8 添加了
Object.entries()
这避免了查找中的每个值原始对象:您可以组合
for...of
、解构和Object.entries
:Object.keys()
和Object.entries()
以与for...in
循环相同的顺序迭代属性,但忽略原型链。 仅迭代对象自身的可枚举属性。Under ECMAScript 5, you can combine
Object.keys()
andArray.prototype.forEach()
:ECMAScript 6 adds
for...of
:ECMAScript 8 adds
Object.entries()
which avoids having to look up each value in the original object:You can combine
for...of
, destructuring, andObject.entries
:Both
Object.keys()
andObject.entries()
iterate properties in the same order as afor...in
loop but ignore the prototype chain. Only the object's own enumerable properties are iterated.你必须使用for-in循环,
但是使用这种循环时要非常小心,因为这会循环原型链上的所有属性。
因此,在使用 for-in 循环时,请始终使用
hasOwnProperty
方法来确定迭代中的当前属性是否确实是您正在检查的对象的属性:You have to use the for-in loop
But be very careful when using this kind of loop, because this will loop all the properties along the prototype chain.
Therefore, when using for-in loops, always make use of the
hasOwnProperty
method to determine if the current property in iteration is really a property of the object you're checking on:如果我们不提及循环对象的替代方法,这个问题就不会完整。
如今,许多著名的 JavaScript 库都提供了自己的方法来迭代集合,即数组、对象和类数组对象。 这些方法使用起来很方便,并且完全兼容任何浏览器。
如果您使用jQuery,则可以使用
jQuery。 each()
方法。 它可用于无缝迭代对象和数组:在 Underscore.js 中,您可以找到方法
_.each()
,它迭代元素列表,依次将每个元素生成提供的函数(注意 iteratee< 中参数的顺序/em> 函数!):_.forEach()
(或其别名_.each ()
) 对于循环对象和数组很有用,但是 (!) 具有length
属性的对象被视为数组,为了避免这种行为,建议使用_.forIn()
和_.forOwn()
方法(这些方法也有value
参数在前):_.forIn()
迭代对象的自己的和继承的可枚举属性,而_.forOwn()
仅迭代< em>自己的对象的属性(基本上检查hasOwnProperty
函数)。 对于简单对象和对象文字,这些方法中的任何一个都可以正常工作。一般来说,所有描述的方法与任何提供的对象都具有相同的行为。 除了使用本机
for..in
循环通常比任何抽象(例如jQuery.each()
)更快之外,这些方法也更加简单使用时,需要更少的编码并提供更好的错误处理。The question won't be complete if we don't mention about alternative methods for looping through objects.
Nowadays many well known JavaScript libraries provide their own methods for iterating over collections, i.e. over arrays, objects, and array-like objects. These methods are convenient to use and are entirely compatible with any browser.
If you work with jQuery, you may use
jQuery.each()
method. It can be used to seamlessly iterate over both objects and arrays:In Underscore.js you can find method
_.each()
, which iterates over a list of elements, yielding each in turn to a supplied function (pay attention to the order of arguments in iteratee function!):Lo-Dash provides several methods for iterating over object properties. Basic
_.forEach()
(or it's alias_.each()
) is useful for looping through both objects and arrays, however (!) objects withlength
property are treated like arrays, and to avoid this behavior it is suggested to use_.forIn()
and_.forOwn()
methods (these also havevalue
argument coming first):_.forIn()
iterates over own and inherited enumerable properties of an object, while_.forOwn()
iterates only over own properties of an object (basically checking againsthasOwnProperty
function). For simple objects and object literals any of these methods will work fine.Generally all described methods have the same behaviour with any supplied objects. Besides using native
for..in
loop will usually be faster than any abstraction, such asjQuery.each()
, these methods are considerably easier to use, require less coding and provide better error handling.前言:
在 2018 年,循环访问对象属性的选项是(列表后面有一些示例):
for-in
[MDN, spec] — 循环结构,循环遍历对象的可枚举属性的名称,包括继承的属性,其名称为字符串Object.keys
[MDN,规范 ] — 一个函数,提供对象的自己、可枚举属性(其名称为字符串)的名称数组。Object.values
[MDN, spec] — 提供对象自己的值数组,可枚举属性。Object.entries
[MDN, spec] — 提供对象的自身、可枚举属性的名称和值数组(数组中的每个条目都是[name, value]
数组)。Object.getOwnPropertyNames
[MDN, spec] — 提供对象的自己属性(甚至是不可枚举的属性)的名称数组,其名称是字符串。Object.getOwnPropertySymbols
[MDN, spec] — 提供对象的自己属性(甚至是不可枚举的属性)的名称数组,其名称为 Symbols。Reflect.ownKeys
[MDN, spec] — 提供对象自己的属性(甚至是不可枚举的属性)的名称数组,无论这些名称是字符串还是符号。Object.getPrototypeOf
[MDN,spec] 并使用Object.getOwnPropertyNames
、Object.getOwnPropertySymbols
或Reflect.ownKeys< /code> 原型链中的每个对象(示例位于本答案的底部)。
除了
for-in
之外的所有这些,您都可以在数组上使用某种循环构造(for
、for-of
、<代码>forEach等)。示例:
for-in
:Object.keys
(使用for-of
循环,但您可以使用任何循环结构):Object.values
:Object.entries
:Object.getOwnPropertyNames
:Object.getOwnPropertySymbols
:Reflect.ownKeys
:所有属性,包括继承的不可枚举属性:
Preface:
Here in 2018, your options for looping through an object's properties are (some examples follow the list):
for-in
[MDN, spec] — A loop structure that loops through the names of an object's enumerable properties, including inherited ones, whose names are stringsObject.keys
[MDN, spec] — A function providing an array of the names of an object's own, enumerable properties whose names are strings.Object.values
[MDN, spec] — A function providing an array of the values of an object's own, enumerable properties.Object.entries
[MDN, spec] — A function providing an array of the names and values of an object's own, enumerable properties (each entry in the array is a[name, value]
array).Object.getOwnPropertyNames
[MDN, spec] — A function providing an array of the names of an object's own properties (even non-enumerable ones) whose names are strings.Object.getOwnPropertySymbols
[MDN, spec] — A function providing an array of the names of an object's own properties (even non-enumerable ones) whose names are Symbols.Reflect.ownKeys
[MDN, spec] — A function providing an array of the names of an object's own properties (even non-enumerable ones), whether those names are strings or Symbols.Object.getPrototypeOf
[MDN, spec] and useObject.getOwnPropertyNames
,Object.getOwnPropertySymbols
, orReflect.ownKeys
on each object in the prototype chain (example at the bottom of this answer).With all of them except
for-in
, you'd use some kind of looping construct on the array (for
,for-of
,forEach
, etc.).Examples:
for-in
:Object.keys
(with afor-of
loop, but you can use any looping construct):Object.values
:Object.entries
:Object.getOwnPropertyNames
:Object.getOwnPropertySymbols
:Reflect.ownKeys
:All properties, including inherited non-enumerable ones:
您可以像这样迭代它:
请注意,
key
不会采用属性的值,它只是一个索引值。You can just iterate over it like:
Note that
key
will not take on the value of the property, it's just an index value.在 ECMAScript 5 中,您在文字迭代字段中采用了新方法 -
Object.keys
您可以在 MDN
我的选择如下,作为当前版本浏览器(Chrome30、IE10、FF25)中更快的解决方案,
您可以比较此方法的性能jsperf.com 上有不同的实现:
您可以在 Kangax 的兼容表
对于旧浏览器,您有 简单 和 完整 polyfill
UPD:
在
perfjs.info
上这个问题中所有最常见案例的性能比较:对象文字迭代
In ECMAScript 5 you have new approach in iteration fields of literal -
Object.keys
More information you can see on MDN
My choice is below as a faster solution in current versions of browsers (Chrome30, IE10, FF25)
You can compare performance of this approach with different implementations on jsperf.com:
Browser support you can see on Kangax's compat table
For old browser you have simple and full polyfill
UPD:
performance comparison for all most popular cases in this question on
perfjs.info
:object literal iteration
今天的性能
2020.03.06 我在 MacOs High Sierra v10.13.6 上的 Chrome v80.0、Safari v13.0.5 和 Firefox 73.0.1 上对所选解决方案进行了测试
结论
for-in
的 解决方案 (A, B) 对于所有浏览器来说,对于大小对象都很快(或最快),for-of
(H) 解决方案在 chrome 上速度很快,对于基于显式索引的 解决方案i< /code> (J,K) 在所有浏览器上对于小对象都相当快(对于 firefox 对于大对象也很快,但在其他浏览器上中等快)
详细信息
针对小对象执行了性能测试
下面的代码片段展示了使用过的解决方案
以下是 chrome 上小对象的结果
Performance
Today 2020.03.06 I perform tests of chosen solutions on Chrome v80.0, Safari v13.0.5 and Firefox 73.0.1 on MacOs High Sierra v10.13.6
Conclusions
for-in
(A,B) are fast (or fastest) for all browsers for big and small objectsfor-of
(H) solution is fast on chrome for small and big objectsi
(J,K) are quite fast on all browsers for small objects (for firefox also fast for big ojbects but medium fast on other browsers)Details
Performance tests was performed for
Below snippets presents used solutions
And here are result for small objects on chrome
注意:您可以对数组执行此操作,但您也将迭代
length
和其他属性。Note: you can do this over arrays, but you'll iterate over the
length
and other properties, too.由于 es2015 变得越来越流行,我发布了这个答案,其中包括使用生成器和迭代器来平滑地迭代
[key, value]
对。 这在其他语言中也是可能的,例如 Ruby。好的,这是一个代码:
有关如何创建迭代器和生成器的所有信息都可以在 Mozilla 开发者页面找到。
希望它对某人有帮助。
编辑:
ES2017 将包含
Object.entries
,这将使迭代对象中的[key, value]
对变得更加容易。 现在已知它将成为 ts39 标准的一部分阶段信息。我认为是时候更新我的答案,让它变得比现在更加新鲜。
您可以在以下位置找到有关使用的更多信息
MDN 页面
Since es2015 is getting more and more popular I am posting this answer which include usage of generator and iterator to smoothly iterate through
[key, value]
pairs. As it is possible in other languages for instance Ruby.Ok here is a code:
All information about how can you do an iterator and generator you can find at developer Mozilla page.
Hope It helped someone.
EDIT:
ES2017 will include
Object.entries
which will make iterating over[key, value]
pairs in objects even more easier. It is now known that it will be a part of a standard according to the ts39 stage information.I think it is time to update my answer to let it became even more fresher than it's now.
You can find more about usage on
MDN page
单行和更具可读性的代码可以是..
Single line and more readable code can be..
浏览完这里的所有答案后,我自己的使用不需要 hasOwnProperty ,因为我的 json 对象是干净的; 添加任何额外的 javascript 处理确实没有任何意义。 这就是我正在使用的全部:
After looking through all the answers in here, hasOwnProperty isn't required for my own usage because my json object is clean; there's really no sense in adding any additional javascript processing. This is all I'm using:
通过 prototype 和 forEach() ,它应该跳过 prototype chain 属性:
via prototype with forEach() which should skip the prototype chain properties:
有趣的是,这些答案中的人们都触及了
Object.keys()
和for...of
但从未将它们组合起来:你不能只是
for...of
一个Object
因为它不是迭代器,而for...index
或.forEach()
Object.keys()
很丑陋/效率低下。我很高兴大多数人都避免使用
for...in
(无论是否检查.hasOwnProperty()
),因为这也有点混乱,所以除了我的答案上面,我在这里想说的是...你可以让普通的对象关联迭代! 行为就像
Map
一样,直接使用花哨的for...of
DEMO 在 Chrome 和 FF 中工作(我假设仅限 ES6)
只要你在下面包含我的垫片:
无需创建一个没有良好语法糖的真实 Map 对象。
事实上,有了这个垫片,如果您仍然想利用 Map 的其他功能(无需将它们全部填充),但仍想使用简洁的对象表示法,因为对象现在是可迭代的,您现在可以从中创建一个 Map!
对于那些不喜欢填充或乱搞
prototype
的人,请随意在窗口上创建该函数,将其称为getObjIterator()
> then;现在你可以将它作为普通函数调用,其他任何事情都不会受到影响
或者
没有理由为什么那行不通。
欢迎来到未来。
It's interesting people in these answers have touched on both
Object.keys()
andfor...of
but never combined them:You can't just
for...of
anObject
because it's not an iterator, andfor...index
or.forEach()
ing theObject.keys()
is ugly/inefficient.I'm glad most people are refraining from
for...in
(with or without checking.hasOwnProperty()
) as that's also a bit messy, so other than my answer above, I'm here to say...You can make ordinary object associations iterate! Behaving just like
Map
s with direct use of the fancyfor...of
DEMO working in Chrome and FF (I assume ES6 only)
So long as you include my shim below:
Without having to create a real Map object that doesn't have the nice syntactic sugar.
In fact, with this shim, if you still wanted to take advantage of Map's other functionality (without shimming them all in) but still wanted to use the neat object notation, since objects are now iterable you can now just make a Map from it!
For those who don't like to shim, or mess with
prototype
in general, feel free to make the function on window instead, calling it something likegetObjIterator()
then;Now you can just call it as an ordinary function, nothing else is affected
or
There's no reason why that wouldn't work.
Welcome to the future.