提问人:Tanmoy 提问时间:3/26/2009 最后编辑:Mateen UlhaqTanmoy 更新时间:12/9/2022 访问量:2773947
如何循环或枚举 JavaScript 对象?
How do I loop through or enumerate a JavaScript object?
问:
我有一个如下所示的JavaScript对象:
var p = {
"p1": "value1",
"p2": "value2",
"p3": "value3"
};
如何遍历所有元素(、、...)并获取它们的键和值?p
p1
p2
p3
答:
for(key in p) {
alert( p[key] );
}
注意:你可以对数组执行此操作,但你也会遍历 和其他属性。length
评论
key
var p = {"p1":"q","p2":"w"}; for(key in p) { alert( key ); }
你可以像这样迭代它:
for (var key in p) {
alert(p[key]);
}
请注意,它不会采用属性的值,它只是一个索引值。key
评论
您可以使用 for-in
循环,如其他人所示。但是,您还必须确保获得的密钥是对象的实际属性,而不是来自原型。
以下是代码片段:
var p = {
"p1": "value1",
"p2": "value2",
"p3": "value3"
};
for (var key in p) {
if (p.hasOwnProperty(key)) {
console.log(key + " -> " + p[key]);
}
}
使用 Object.keys() 替代的 for-of:
var p = {
0: "value1",
"b": "value2",
key: "value3"
};
for (var key of Object.keys(p)) {
console.log(key + " -> " + p[key])
}
请注意,使用 for-of 而不是 for-in
,如果不使用,它将在命名属性上返回 undefined,并且 Object.keys()
确保仅使用对象自己的属性,而不使用整个原型链属性
使用新的 Object.entries()
方法:
注意:Internet Explorer 本身不支持此方法。您可以考虑对较旧的浏览器使用 Polyfill。
const p = {
"p1": "value1",
"p2": "value2",
"p3": "value3"
};
for (const [key, value] of Object.entries(p)) {
console.log(`${key}: ${value}`);
}
评论
for..in
hasOwnProperty
Object.keys
您必须使用 for-in 循环
但是在使用这种循环时要非常小心,因为这将沿原型链循环所有属性。
因此,在使用 for-in 循环时,请始终使用该方法来确定迭代中的当前属性是否确实是要检查的对象的属性:hasOwnProperty
for (var prop in p) {
if (!p.hasOwnProperty(prop)) {
//The current property is not a direct property of p
continue;
}
//Do your logic with the property here
}
评论
{ }
if
if
{ }
if
在 ECMAScript 5 下,你可以将 Object.keys
() 和 Array.prototype.forEach()
组合在一起:
var obj = { first: "John", last: "Doe" };
Object.keys(obj).forEach(function(key) {
console.log(key, obj[key]);
});
ECMAScript 6 增加了...的
:
for (const key of Object.keys(obj)) {
console.log(key, obj[key]);
}
ECMAScript 8 添加了 Object.entries(),
它避免了在原始对象中查找每个值:
Object.entries(obj).forEach(
([key, value]) => console.log(key, value)
);
您可以将 、 解构和 :for...of
Object.entries
for (const [key, value] of Object.entries(obj)) {
console.log(key, value);
}
和 都以与循环相同的顺序迭代属性,但忽略原型链。仅迭代对象自身的可枚举属性。Object.keys()
Object.entries()
for...in
评论
Object.forEach(obj, function (value, key) {...})
obj.forEach(function...)
Array.prototype.forEach
forEach
Object.keys
在浏览了这里的所有答案之后,我自己的使用不需要hasOwnProperty,因为我的json对象是干净的;添加任何额外的 JavaScript 处理真的没有意义。这就是我正在使用的全部内容:
for (var key in p) {
console.log(key + ' => ' + p[key]);
// key is key
// value is p[key]
}
评论
Object.prototype
for..in
hasOwnProperty
Object.create(null)
var p = {
"p1": "value1",
"p2": "value2",
"p3": "value3"
};
for (var key in p) {
if (p.hasOwnProperty(key)) {
console.log(key + " = " + p[key]);
}
}
<p>
Output:<br>
p1 = values1<br>
p2 = values2<br>
p3 = values3
</p>
通过带有 forEach() 的原型,它应该跳过原型链属性:
Object.prototype.each = function(f) {
var obj = this
Object.keys(obj).forEach( function(key) {
f( key , obj[key] )
});
}
//print all keys and values
var obj = {a:1,b:2,c:3}
obj.each(function(key,value) { console.log(key + " " + value) });
// a 1
// b 2
// c 3
评论
obj = { print: 1, each: 2, word: 3 }
TypeError: number is not a function
forEach
Array
如果我们不提及循环遍历对象的替代方法,那么这个问题就不完整。
如今,许多著名的 JavaScript 库都提供了自己的方法来迭代集合,即遍历数组、对象和类似数组的对象。这些方法使用方便,并且与任何浏览器完全兼容。
如果您使用 jQuery,则可以使用
jQuery.each()
方法。它可用于无缝迭代对象和数组:$.each(obj, function(key, value) { console.log(key, value); });
在 Underscore.js 中,您可以找到方法
_.each(),
它遍历元素列表,依次将每个元素生成为提供的函数(注意迭代函数中参数的顺序!_.each(obj, function(value, key) { console.log(key, value); });
Lo-Dash 提供了几种迭代对象属性的方法。基本的
_.forEach
() (或其别名 )对于遍历对象和数组都很有用,但是 (!) 具有属性的对象被视为数组,为了避免这种行为,建议使用 _.forIn
() 和_.forOwn() 方法(
这些方法也有参数在前):_.each()
length
value
_.forIn(obj, function(value, key) { console.log(key, value); });
_.forIn()
遍历对象的自有和继承的可枚举属性,而仅遍历对象的自有属性(基本上是针对函数进行检查)。对于简单对象和对象文本,这些方法中的任何一个都可以正常工作。_.forOwn()
hasOwnProperty
通常,所有描述的方法对任何提供的对象都具有相同的行为。此外,使用原生循环通常比任何抽象都快,例如,这些方法相当容易使用,需要更少的编码并提供更好的错误处理。for..in
jQuery.each()
评论
在 ECMAScript 5 中,您在文字的迭代字段中有了新的方法——Object.keys
更多信息可以在 MDN 上看到
我的选择如下,作为当前版本的浏览器(Chrome30、IE10、FF25)中更快的解决方案
var keys = Object.keys(p),
len = keys.length,
i = 0,
prop,
value;
while (i < len) {
prop = keys[i];
value = p[prop];
i += 1;
}
您可以在 jsperf.com 上将此方法的性能与不同的实现进行比较:
您可以在 Kangax 的兼容性表上看到浏览器支持
更新:
这个问题中所有最常见案例的性能比较:perfjs.info
只有没有依赖项的 JavaScript 代码:
var p = {"p1": "value1", "p2": "value2", "p3": "value3"};
keys = Object.keys(p); // ["p1", "p2", "p3"]
for(i = 0; i < keys.length; i++){
console.log(keys[i] + "=" + p[keys[i]]); // p1=value1, p2=value2, p3=value3
}
Object.keys(obj) : 数组
检索所有可枚举的自己的(非继承的)属性的所有字符串值键。
因此,它通过使用 hasOwnProperty 测试每个对象键来提供与预期相同的键列表。您不需要额外的测试操作,并且应该更快。让我们来证明一下:Object.keys( obj ).forEach(function( key ){})
var uniqid = function(){
var text = "",
i = 0,
possible = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
for( ; i < 32; i++ ) {
text += possible.charAt( Math.floor( Math.random() * possible.length ) );
}
return text;
},
CYCLES = 100000,
obj = {},
p1,
p2,
p3,
key;
// Populate object with random properties
Array.apply( null, Array( CYCLES ) ).forEach(function(){
obj[ uniqid() ] = new Date()
});
// Approach #1
p1 = performance.now();
Object.keys( obj ).forEach(function( key ){
var waste = obj[ key ];
});
p2 = performance.now();
console.log( "Object.keys approach took " + (p2 - p1) + " milliseconds.");
// Approach #2
for( key in obj ) {
if ( obj.hasOwnProperty( key ) ) {
var waste = obj[ key ];
}
}
p3 = performance.now();
console.log( "for...in/hasOwnProperty approach took " + (p3 - p2) + " milliseconds.");
在我的Firefox中,我有以下结果
- Object.keys 方法耗时 40.21101451665163 毫秒。
- 为。。。in/hasOwnProperty 方法耗时 98.26163508463651 毫秒。
在Chrome上,差异甚至更大 http://codepen.io/dsheiko/pen/JdrqXa
PS2:在 ES6 (EcmaScript 2015) 中,您可以更好地迭代可迭代对象:
let map = new Map().set('a', 1).set('b', 2);
for (let pair of map) {
console.log(pair);
}
// OR
let map = new Map([
[false, 'no'],
[true, 'yes'],
]);
map.forEach((value, key) => {
console.log(key, value);
});
评论
我会这样做,而不是在每个循环中检查。obj.hasOwnerProperty
for ... in
var obj = {a : 1};
for(var key in obj){
//obj.hasOwnProperty(key) is not needed.
console.log(key);
}
//then check if anybody has messed the native object. Put this code at the end of the page.
for(var key in Object){
throw new Error("Please don't extend the native object");
}
使用纯 JavaScript 时,循环可能非常有趣。似乎只有 ECMA6(2015 年新 JavaScript 规范)控制了循环。不幸的是,在我写这篇文章的时候,浏览器和流行的集成开发环境(IDE)仍在努力完全支持新的花里胡哨的东西。
一目了然,这是 ECMA6 之前的 JavaScript 对象循环的样子:
for (var key in object) {
if (p.hasOwnProperty(key)) {
var value = object[key];
console.log(key); // This is the key;
console.log(value); // This is the value;
}
}
另外,我知道这超出了这个问题的范围,但在 2011 年,ECMAScript 5.1 添加了仅数组的方法,这基本上创造了一种新的改进方法来循环遍历数组,同时仍然保留不可迭代的对象与旧的冗长和令人困惑的循环。但奇怪的是,这种新方法不支持,这导致了各种其他问题。forEach
for
forEach
break
基本上在 2011 年,除了许多流行的库(jQuery、Underscore 等)决定重新实现之外,没有一种真正可靠的方法来循环 JavaScript。
截至 2015 年,我们现在有一种更好的开箱即用方法来循环(和中断)任何对象类型(包括数组和字符串)。以下是当推荐成为主流时 JavaScript 中的循环最终会是什么样子:
for (let [key, value] of Object.entries(object)) {
console.log(key); // This is the key;
console.log(value); // This is the value;
}
请注意,自 2016 年 6 月 18 日起,大多数浏览器将不支持上述代码。即使在 Chrome 中,您也需要启用此特殊标志才能使其工作:chrome://flags/#enable-javascript-harmony
在这成为新标准之前,仍然可以使用旧方法,但在流行的库中也有替代方案,甚至是那些不使用任何这些库的人的轻量级替代方案。
评论
Uncaught TypeError: Object.entries is not a function
有趣的是,这些答案中的人们都触及了两者,但从未将它们结合起来:Object.keys()
for...of
var map = {well:'hello', there:'!'};
for (let key of Object.keys(map))
console.log(key + ':' + map[key]);
你不能只是为了...
的对象
,因为它不是迭代器,并且...index
或 .forEach() 将 Object.keys() 与 Object.keys()
联系起来是丑陋的/低效的。
我很高兴大多数人都避免......(
无论是否检查 .hasOwnProperty()
),因为这也有点混乱,所以除了我上面的答案之外,我在这里要说......
你可以让普通的对象关联迭代!行为就像地图
一样,直接使用花哨的...
在 Chrome 和 FF 中工作的 DEMO(我假设仅限 ES6)
var ordinaryObject = {well:'hello', there:'!'};
for (let pair of ordinaryObject)
//key:value
console.log(pair[0] + ':' + pair[1]);
//or
for (let [key, value] of ordinaryObject)
console.log(key + ':' + value);
只要你在下面包括我的垫片:
//makes all objects iterable just like Maps!!! YAY
//iterates over Object.keys() (which already ignores prototype chain for us)
Object.prototype[Symbol.iterator] = function() {
var keys = Object.keys(this)[Symbol.iterator]();
var obj = this;
var output;
return {next:function() {
if (!(output = keys.next()).done)
output.value = [output.value, obj[output.value]];
return output;
}};
};
而不必创建一个没有好语法糖的真实 Map 对象。
var trueMap = new Map([['well', 'hello'], ['there', '!']]);
for (let pair of trueMap)
console.log(pair[0] + ':' + pair[1]);
事实上,有了这个填充码,如果你仍然想利用 Map 的其他功能(而不是将它们全部填充),但仍然想使用简洁的对象符号,因为对象现在是可迭代的,你现在可以用它制作一个 Map!
//shown in demo
var realMap = new Map({well:'hello', there:'!'});
对于那些不喜欢填充或弄乱原型
的人,可以随意在窗口上创建函数,然后将其称为 getObjIterator();
//no prototype manipulation
function getObjIterator(obj) {
//create a dummy object instead of adding functionality to all objects
var iterator = new Object();
//give it what the shim does but as its own local property
iterator[Symbol.iterator] = function() {
var keys = Object.keys(obj)[Symbol.iterator]();
var output;
return {next:function() {
if (!(output = keys.next()).done)
output.value = [output.value, obj[output.value]];
return output;
}};
};
return iterator;
}
现在你可以把它作为一个普通函数来调用,其他任何内容都不会受到影响
var realMap = new Map(getObjIterator({well:'hello', there:'!'}))
或
for (let pair of getObjIterator(ordinaryObject))
欢迎来到未来。
评论
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 like getObjIterator() then;
ordinaryObject
由于 es2015 越来越受欢迎,我发布了这个答案,其中包括使用生成器和迭代器来平滑地迭代成对。正如在其他语言中一样,例如 Ruby。[key, value]
好的,这里有一个代码:
const MyObject = {
'a': 'Hello',
'b': 'it\'s',
'c': 'me',
'd': 'you',
'e': 'looking',
'f': 'for',
[Symbol.iterator]: function*() {
for (const i of Object.keys(this)) {
yield [i, this[i]];
}
}
};
for (const [k, v] of MyObject) {
console.log(`Here is key ${k} and here is value ${v}`);
}
有关如何执行迭代器和生成器的所有信息,都可以在开发人员Mozilla页面上找到。
希望它帮助了某人。
编辑:
ES2017 将包括这将使对象中的对迭代更加容易。现在已知,根据 ts39 阶段信息,它将成为标准的一部分。Object.entries
[key, value]
我认为是时候更新我的答案了,让它变得比现在更新鲜。
const MyObject = {
'a': 'Hello',
'b': 'it\'s',
'c': 'me',
'd': 'you',
'e': 'looking',
'f': 'for',
};
for (const [k, v] of Object.entries(MyObject)) {
console.log(`Here is key ${k} and here is value ${v}`);
}
你可以在 MDN 页面上找到更多关于用法的信息
评论
在 ES6 中,我们有众所周知的符号来公开一些以前的内部方法,你可以用它来定义迭代器如何为这个对象工作:
var p = {
"p1": "value1",
"p2": "value2",
"p3": "value3",
*[Symbol.iterator]() {
yield *Object.keys(this);
}
};
[...p] //["p1", "p2", "p3"]
这将给出与使用 for 相同的结果...在 ES6 循环中。
for(var key in p) {
console.log(key);
}
但重要的是要知道你现在使用 es6 所拥有的功能!
评论
Object.keys()
您可以向所有对象添加一个简单的 forEach 函数,以便您可以自动遍历任何对象:
Object.defineProperty(Object.prototype, 'forEach', {
value: function (func) {
for (var key in this) {
if (!this.hasOwnProperty(key)) {
// skip loop if the property is from prototype
continue;
}
var value = this[key];
func(key, value);
}
},
enumerable: false
});
对于那些不喜欢“为了......in“方法:
Object.defineProperty(Object.prototype, 'forEach', {
value: function (func) {
var arr = Object.keys(this);
for (var i = 0; i < arr.length; i++) {
var key = arr[i];
func(key, this[key]);
}
},
enumerable: false
});
现在,您可以简单地调用:
p.forEach (function(key, value){
console.log ("Key: " + key);
console.log ("Value: " + value);
});
如果您不想与其他 forEach-Methods 发生冲突,则可以使用您的唯一名称来命名它。
评论
Object
该方法返回给定对象自己的可枚举属性的数组。在这里阅读更多关于它的信息Object.keys()
var p = {
"p1": "value1",
"p2": "value2",
"p3": "value3"
};
Object.keys(p).map((key)=> console.log(key + "->" + p[key]))
这是遍历对象的另一种方法。
var p = {
"p1": "value1",
"p2": "value2",
"p3": "value3"
};
Object.keys(p).forEach(key => { console.log(key, p[key]) })
评论
for
前言:
- 对象属性可以是自己的(属性位于对象本身上),也可以是继承的(不是在对象本身上,而是在其原型之一上)。
- 对象属性可以是可枚举的,也可以是不可枚举的。不可枚举的属性被排除在许多属性枚举/数组之外。
- 属性名称可以是字符串或符号。名称为 Symbols 的属性被排除在许多属性枚举/数组之外。
在 2018 年,循环遍历对象属性的选项如下(列表后面有一些示例):
for-in
[MDN, spec] — 一个循环结构,循环遍历对象的可枚举属性的名称,包括继承的属性,其名称为字符串Object.keys
[MDN, spec] — 一个函数,提供对象自己的可枚举属性的名称数组,这些属性的名称是字符串。Object.values
[MDN, spec] — 一个函数,提供对象自己的可枚举属性的值数组。Object.entries
[MDN, spec] — 一个函数,提供对象自己的可枚举属性的名称和值的数组(数组中的每个条目都是一个数组)。[name, value]
Object.getOwnPropertyNames
[MDN, spec] — 一个函数,提供对象自身属性(甚至是不可枚举的属性)名称的数组,其名称为字符串。Object.getOwnPropertySymbols
[MDN, spec] — 一个函数,提供对象自身属性(甚至是不可枚举的属性)名称的数组,其名称为 Symbols。Reflect.ownKeys
[MDN, spec] — 一个函数,提供对象自身属性(甚至是不可枚举的属性)的名称数组,无论这些名称是字符串还是符号。- 如果你想要一个对象的所有属性,包括不可枚举的继承属性,你需要使用循环和 [MDN, spec] 并使用 、 或 原型链中的每个对象(本答案底部的示例)。
Object.getPrototypeOf
Object.getOwnPropertyNames
Object.getOwnPropertySymbols
Reflect.ownKeys
对于除 之外的所有方法,您将在数组(、、等)上使用某种循环结构。for-in
for
for-of
forEach
例子:
进场
:
// A prototype object to inherit from, with a string-named property
const p = {answer: 42};
// The object we'll look at, which inherits from `p`
const o = Object.create(p);
// A string-named property
o.question = "Life, the Universe, and Everything";
// A symbol-named property
o[Symbol("author")] = "Douglas Adams";
for (const name in o) {
const value = o[name];
console.log(`${name} = ${value}`);
}
Object.keys
(带有 for-of
循环,但您可以使用任何循环结构):
// A prototype object to inherit from, with a string-named property
const p = {answer: 42};
// The object we'll look at, which inherits from `p`
const o = Object.create(p);
// A string-named property
o.question = "Life, the Universe, and Everything";
// A symbol-named property
o[Symbol("author")] = "Douglas Adams";
for (const name of Object.keys(o)) {
const value = o[name];
console.log(`${name} = ${value}`);
}
Object.values
:
// A prototype object to inherit from, with a string-named property
const p = {answer: 42};
// The object we'll look at, which inherits from `p`
const o = Object.create(p);
// A string-named property
o.question = "Life, the Universe, and Everything";
// A symbol-named property
o[Symbol("author")] = "Douglas Adams";
for (const value of Object.values(o)) {
console.log(`${value}`);
}
Object.entries
:
// A prototype object to inherit from, with a string-named property
const p = {answer: 42};
// The object we'll look at, which inherits from `p`
const o = Object.create(p);
// A string-named property
o.question = "Life, the Universe, and Everything";
// A symbol-named property
o[Symbol("author")] = "Douglas Adams";
for (const [name, value] of Object.entries(o)) {
console.log(`${name} = ${value}`);
}
Object.getOwnPropertyNames
:
// A prototype object to inherit from, with a string-named property
const p = {answer: 42};
// The object we'll look at, which inherits from `p`
const o = Object.create(p);
// A string-named property
o.question = "Life, the Universe, and Everything";
// A symbol-named property
o[Symbol("author")] = "Douglas Adams";
for (const name of Object.getOwnPropertyNames(o)) {
const value = o[name];
console.log(`${name} = ${value}`);
}
Object.getOwnPropertySymbols
:
// A prototype object to inherit from, with a string-named property
const p = {answer: 42};
// The object we'll look at, which inherits from `p`
const o = Object.create(p);
// A string-named property
o.question = "Life, the Universe, and Everything";
// A symbol-named property
o[Symbol("author")] = "Douglas Adams";
for (const name of Object.getOwnPropertySymbols(o)) {
const value = o[name];
console.log(`${String(name)} = ${value}`);
}
Reflect.ownKeys
:
// A prototype object to inherit from, with a string-named property
const p = {answer: 42};
// The object we'll look at, which inherits from `p`
const o = Object.create(p);
// A string-named property
o.question = "Life, the Universe, and Everything";
// A symbol-named property
o[Symbol("author")] = "Douglas Adams";
for (const name of Reflect.ownKeys(o)) {
const value = o[name];
console.log(`${String(name)} = ${value}`);
}
所有属性,包括继承的不可枚举属性:
// A prototype object to inherit from, with a string-named property
const p = {answer: 42};
// The object we'll look at, which inherits from `p`
const o = Object.create(p);
// A string-named property
o.question = "Life, the Universe, and Everything";
// A symbol-named property
o[Symbol("author")] = "Douglas Adams";
for (let depth = 0, current = o; current; ++depth, current = Object.getPrototypeOf(current)) {
for (const name of Reflect.ownKeys(current)) {
const value = o[name];
console.log(`[${depth}] ${String(name)} = ${String(value)}`);
}
}
.as-console-wrapper {
max-height: 100% !important;
}
评论
在最新的 ES 脚本中,您可以执行如下操作:
let p = {foo: "bar"};
for (let [key, value] of Object.entries(p)) {
console.log(key, value);
}
评论
您还可以使用 Object.keys() 并遍历对象键,如下所示以获取值:
var p = {
"p1": "value1",
"p2": "value2",
"p3": "value3"
};
Object.keys(p).forEach((key)=> {
console.log(key +' -> '+ p[key]);
});
评论
在 Object.keys()
上使用 for-of
喜欢:
let object = {
"key1": "value1",
"key2": "value2",
"key3": "value3"
};
for (let key of Object.keys(object)) {
console.log(key + " : " + object[key])
}
在 javascript 中迭代对象的多种方式
用于...在循环中
var p = {
"p1": "value1",
"p2": "value2",
"p3": "value3"
};
for (let key in p){
if(p.hasOwnProperty(key)){
console.log(`${key} : ${p[key]}`)
}
}
用于...OF 循环
var p = {
"p1": "value1",
"p2": "value2",
"p3": "value3"
};
for (let key of Object.keys(p)){
console.log(`key: ${key} & value: ${p[key]}`)
}
将 forEach() 与 Object.keys、Object.values、Object.entries 一起使用
var p = {
"p1": "value1",
"p2": "value2",
"p3": "value3"
};
Object.keys(p).forEach(key=>{
console.log(`${key} : ${p[key]}`);
});
Object.values(p).forEach(value=>{
console.log(value);
});
Object.entries(p).forEach(([key,value])=>{
console.log(`${key}:${value}`)
})
循环使用可枚举的 JavaScript 对象的一个好方法是使用 or with using 函数,这对 ReactJS 来说可能很棒且很常见。如下图所示:Object.keys
Object.entries
map
// assume items:
const items = {
first: { name: 'phone', price: 400 },
second: { name: 'tv', price: 300 },
third: { name: 'sofa', price: 250 },
};
用于循环并显示一些 UI,如下所示:ReactJS
~~~
<div>
{Object.entries(items).map(([key, ({ name, price })]) => (
<div key={key}>
<span>name: {name}</span>
<span>price: {price}</span>
</div>
))}
</div>
实际上,我使用了两次解构赋值,一次用于获取,一次用于获取和.key
name
price
评论
<Fragment>
how for loops don't work inside <Fragment>
性能
今天 2020.03.06 我在 MacOs High Sierra v80.0.5 上的 Chrome v13.0.5、Safari v13.0.5 和 Firefox 10.13.6 上对选定的解决方案进行了测试
结论
- 基于(A,B)的解决方案对于所有浏览器的大型和小型对象都是快速(或最快)的
for-in
- 令人惊讶的是,(H)解决方案在铬上对小型和大型物体都很快
for-of
- 基于显式索引 (J,K) 的解决方案在所有浏览器上对于小对象都非常快(对于 firefox,对于大 ojbects 也很快,但在其他浏览器上速度中等)
i
- 基于迭代器(D,E)的解决方案最慢,不推荐使用
- 解决方案 C 对于大物体是慢速的,对于小物体是中慢的
详
进行了性能测试
以下代码片段介绍了使用的解决方案
function A(obj,s='') {
for (let key in obj) if (obj.hasOwnProperty(key)) s+=key+'->'+obj[key] + ' ';
return s;
}
function B(obj,s='') {
for (let key in obj) s+=key+'->'+obj[key] + ' ';
return s;
}
function C(obj,s='') {
const map = new Map(Object.entries(obj));
for (let [key,value] of map) s+=key+'->'+value + ' ';
return s;
}
function D(obj,s='') {
let o = {
...obj,
*[Symbol.iterator]() {
for (const i of Object.keys(this)) yield [i, this[i]];
}
}
for (let [key,value] of o) s+=key+'->'+value + ' ';
return s;
}
function E(obj,s='') {
let o = {
...obj,
*[Symbol.iterator]() {yield *Object.keys(this)}
}
for (let key of o) s+=key+'->'+o[key] + ' ';
return s;
}
function F(obj,s='') {
for (let key of Object.keys(obj)) s+=key+'->'+obj[key]+' ';
return s;
}
function G(obj,s='') {
for (let [key, value] of Object.entries(obj)) s+=key+'->'+value+' ';
return s;
}
function H(obj,s='') {
for (let key of Object.getOwnPropertyNames(obj)) s+=key+'->'+obj[key]+' ';
return s;
}
function I(obj,s='') {
for (const key of Reflect.ownKeys(obj)) s+=key+'->'+obj[key]+' ';
return s;
}
function J(obj,s='') {
let keys = Object.keys(obj);
for(let i = 0; i < keys.length; i++){
let key = keys[i];
s+=key+'->'+obj[key]+' ';
}
return s;
}
function K(obj,s='') {
var keys = Object.keys(obj), len = keys.length, i = 0;
while (i < len) {
let key = keys[i];
s+=key+'->'+obj[key]+' ';
i += 1;
}
return s;
}
function L(obj,s='') {
Object.keys(obj).forEach(key=> s+=key+'->'+obj[key]+' ' );
return s;
}
function M(obj,s='') {
Object.entries(obj).forEach(([key, value]) => s+=key+'->'+value+' ');
return s;
}
function N(obj,s='') {
Object.getOwnPropertyNames(obj).forEach(key => s+=key+'->'+obj[key]+' ');
return s;
}
function O(obj,s='') {
Reflect.ownKeys(obj).forEach(key=> s+=key+'->'+obj[key]+' ' );
return s;
}
// TEST
var p = {
"p1": "value1",
"p2": "value2",
"p3": "value3"
};
let log = (name,f) => console.log(`${name} ${f(p)}`)
log('A',A);
log('B',B);
log('C',C);
log('D',D);
log('E',E);
log('F',F);
log('G',G);
log('H',H);
log('I',I);
log('J',J);
log('K',K);
log('L',L);
log('M',M);
log('N',N);
log('O',O);
This snippet only presents choosen solutions
这是铬上小物体的结果
评论
单行和更易读的代码可以..
Object.entries(myObject).map(([key, value]) => console.log(key, value))
评论
Object.entries(myObject).map(([key, value]) => console.log(key, value))
你可以试试这样。 将某某,这将产生键和值。所以这里的键是 ,值是 ,而 值就像 、 一样。myObject
{name: "", phone: ""}
name
phone
dog
123123
例{name: "dog"}
这里键是,值是。name
dog
评论
将对象传递给 。这将返回一个包含对象中所有键的数组。然后,您可以使用 遍历数组。使用 where 是您的对象,并且是映射迭代中的当前值,您可以获取该键/属性的值。Object.keys()
map
obj[key]
obj
key
const obj = { name: "Jane", age: 50 };
Object.keys(obj).map( key => {
console.log(key, obj[key]);
});
评论