如何循环或枚举JavaScript对象?

我有一个JavaScript对象,如下所示:

var p = {"p1": "value1","p2": "value2","p3": "value3"};

如何遍历p的所有元素(p1p2p3…)并获取它们的键和值?

2669466 次浏览
for(key in p) {alert( p[key] );}

注意:您可以在数组上执行此操作,但您也将迭代length和其他属性。

你可以像这样迭代它:

for (var key in p) {alert(p[key]);}

请注意,key不会接受属性的值,它只是一个索引值。

你可以像其他人展示的那样使用#0循环。但是,你还必须确保你得到的键是对象的实际属性,而不是来自原型。

这是代码片段:

var p = {"p1": "value1","p2": "value2","p3": "value3"};
for (var key in p) {if (p.hasOwnProperty(key)) {console.log(key + " -> " + p[key]);}}

用Object.keys()替代:

var p = {0: "value1","b": "value2",key: "value3"};
for (var key of Object.keys(p)) {console.log(key + " -> " + p[key])}

注意使用#0而不是#1,如果不使用它将在命名属性上返回未定义,并且#2确保仅使用对象自己的属性而不使用整个原型链属性

使用新的Object.entries()方法:

备注: Internet Explorer本身不支持此方法。您可以考虑对旧浏览器使用Polyill。

const p = {"p1": "value1","p2": "value2","p3": "value3"};
for (let [key, value] of Object.entries(p)) {console.log(`${key}: ${value}`);}

你必须使用换入循环

但是使用这种循环时要非常小心,因为这将沿着原型链循环所有属性

因此,在使用for-in循环时,始终使用hasOwnProperty方法来确定迭代中的当前属性是否真的是您要检查的对象的属性:

for (var prop in p) {if (!p.hasOwnProperty(prop)) {//The current property is not a direct property of pcontinue;}//Do your logic with the property here}

在ECMAScript 5下,您可以组合#0#1

var obj = { first: "John", last: "Doe" };
Object.keys(obj).forEach(function(key) {console.log(key, obj[key]);});

ECMAScript 6增加了#0

for (const key of Object.keys(obj)) {console.log(key, obj[key]);}

ECMAScript 8增加了#0,避免了在原始对象中查找每个值:

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循环但忽略原型链相同的顺序迭代属性。只迭代对象自己的可枚举属性。

在浏览了这里的所有答案之后,我自己的使用不需要hasOwnProperty,因为我的json对象是干净的;添加任何额外的javascript处理真的没有意义。这就是我使用的全部:

for (var key in p) {console.log(key + ' => ' + p[key]);// key is key// value is p[key]}

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 = thisObject.keys(obj).forEach( function(key) {f( key , obj[key] )});}

//print all keys and valuesvar obj = {a:1,b:2,c:3}obj.each(function(key,value) { console.log(key + " " + value) });// a 1// b 2// c 3

如果我们不提到循环对象的替代方法,这个问题就不完整。

如今,许多著名的JavaScript库都提供了自己的方法来迭代集合,即超过数组对象类数组对象。这些方法使用方便,并且与任何浏览器完全兼容。

  1. 如果您使用jQuery,您可以使用#0方法。它可用于无缝迭代对象和数组:

    $.each(obj, function(key, value) {console.log(key, value);});
  2. 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!):

    _.each(obj, function(value, key) {console.log(key, value);});
  3. 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 with length property are treated like arrays, and to avoid this behavior it is suggested to use _.forIn() and _.forOwn() methods (these also have value argument coming first):

    _.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上比较这种方法与不同实现的性能:

您可以在康加克斯的同桌上看到的浏览器支持

对于旧的浏览器,您有简单充分的Poly填充

UPD:

这个问题中所有最流行的情况下的性能比较perfjs.info

对象文字迭代

因为asker的['最终目标是遍历一些键值对'],最后不要寻找循环。

var p ={"p1":"value1","p2":"value2","p3":"value3"};if('p1' in p){var val=p['p1'];...}

只有没有依赖项的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 propertiesArray.apply( null, Array( CYCLES ) ).forEach(function(){obj[ uniqid() ] = new Date()});
// Approach #1p1 = 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 #2for( 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毫秒。
  • for… in/hasOwnProperty方法耗时98.26163508463651毫秒。

PS.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);}
// ORlet map = new Map([[false, 'no'],[true,  'yes'],]);map.forEach((value, key) => {console.log(key, value);});

我会这样做,而不是在每个for ... in循环中检查obj.hasOwnerProperty

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");}

如果您也想迭代不可枚举的属性,您可以使用#0返回直接在给定对象上找到的所有属性(可枚举或不可枚举)的数组。

var obj = Object.create({}, {// non-enumerable propertygetFoo: {value: function() { return this.foo; },enumerable: false}});
obj.foo = 1; // enumerable property
Object.getOwnPropertyNames(obj).forEach(function (name) {document.write(name + ': ' + obj[name] + '<br/>');});

从ES2015开始,您可以使用for of循环直接访问元素:

// before ES2015for(var key of elements){console.log(elements[key]);}

// ES2015for(let element of elements){console.log(element);}

希望这有助于某人。

当使用纯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

在这成为新标准之前,旧方法仍然可以使用,但在流行的库中也有替代方案,甚至对于那些不使用这些库的人来说轻量级替代品

有趣的是,这些答案中的人都提到了Object.keys()for...of,但从未将它们结合起来:

var map = {well:'hello', there:'!'};for (let key of Object.keys(map))console.log(key + ':' + map[key]);

你不能只是for...of一个Object,因为它不是迭代器,for...index.forEach()Object.keys()是丑陋/低效的。
我很高兴大多数人都在克制for...in(有或没有检查.hasOwnProperty()),因为这也有点混乱,所以除了我上面的答案,我在这里说…


你可以让普通的对象关联迭代!行为就像#0一样,直接使用花哨的#1
DEMO在Chrome和FF中工作(我假设只有ES6)

var ordinaryObject = {well:'hello', there:'!'};for (let pair of ordinaryObject)//key:valueconsole.log(pair[0] + ':' + pair[1]);
//orfor (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 demovar realMap = new Map({well:'hello', there:'!'});

对于那些不喜欢垫片,或者一般不喜欢prototype的人,请随意在windows上制作函数,然后将其称为getObjIterator()

//no prototype manipulationfunction getObjIterator(obj) {//create a dummy object instead of adding functionality to all objectsvar iterator = new Object();
//give it what the shim does but as its own local propertyiterator[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))

这没有理由行不通。

欢迎来到未来。

如果有人需要遍历条件对象

var arrayObjects = [{"building":"A", "status":"good"},{"building":"B","status":"horrible"}];
for (var i=0; i< arrayObjects.length; i++) {console.log(arrayObjects[i]);  
for(key in arrayObjects[i]) {    
if (key == "status" && arrayObjects[i][key] == "good") {        
console.log(key + "->" + arrayObjects[i][key]);}else{console.log("nothing found");}}}

由于es2015越来越受欢迎,我发布了这个答案,其中包括使用生成器和迭代器来平滑地迭代[key, value]对。在其他语言中,例如Ruby。

这里有一个代码:

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将包含Object.entries,这将使在对象中迭代[key, value]对更加容易。现在已知根据ts39阶段信息,它将成为标准的一部分。

我想是时候更新我的答案了,让它变得比现在更新鲜。

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,我想添加我自己的糖勺,并提供另一种方法来迭代对象的属性。

由于普通JS对象不是开箱即用的迭代,我们无法使用for..of循环来迭代其内容。但是没有人能阻止我们使其可迭代

让我们有book对象。

let book = {title: "Amazing book",author: "Me",pages: 3}
book[Symbol.iterator] = function(){
let properties = Object.keys(this); // returns an array with property nameslet counter = 0;let isDone = false;
let next = () => {if(counter >= properties.length){isDone = true;}return { done: isDone, value: this[properties[counter++]] }}
return { next };}

既然我们已经这样做了,我们可以这样使用它:

for(let pValue of book){console.log(pValue);}------------------------Amazing bookMe3

或者如果你知道ES6发电机的强大功能,那么你当然可以让上面的代码更短。

book[Symbol.iterator] = function *(){
let properties = Object.keys(this);for (let p of properties){yield this[p];}
}

当然,您可以将这种行为应用于所有对象,并使Objectprototype级别上可迭代。

Object.prototype[Symbol.iterator] = function() {...}

此外,符合可迭代协议的对象可以与新的ES2015功能传播运算符一起使用,因此我们可以将对象属性值作为数组读取。

let pValues = [...book];console.log(pValues);-------------------------["Amazing book", "Me", 3]

或者你可以使用解构赋值:

let [title, , pages] = book; // notice that we can just skip unnecessary valuesconsole.log(title);console.log(pages);------------------Amazing book3

您可以使用我上面提供的所有代码查看JS Fiddle

在ES6中,我们有一些众所周知的符号来公开一些以前的内部方法,你可以用它来定义迭代器如何为这个对象工作:

var p = {"p1": "value1","p2": "value2","p3": "value3",*[Symbol.iterator]() {yield *Object.keys(this);}};
[...p] //["p1", "p2", "p3"]

这将给出与在es6循环中使用for…相同的结果。

for(var key in p) {console.log(key);}

但重要的是要知道你现在使用es6的能力!

您可以向所有对象添加一个简单的for每个函数,因此您可以自动循环遍历任何对象:

Object.defineProperty(Object.prototype, 'forEach', {value: function (func) {for (var key in this) {if (!this.hasOwnProperty(key)) {// skip loop if the property is from prototypecontinue;}var value = this[key];func(key, value);}},enumerable: false});

对于那些不喜欢“为…在”方法的人:

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-方法发生冲突,您可以使用您的唯一名称来命名它。

我在使用Angular时遇到了类似的问题,这是我找到的解决方案。

步骤1。获取所有对象键。使用Object.keys.此方法返回给定对象自己的可枚举属性的数组。

步骤2。创建一个空数组。这是一个所有属性都将存在的地方,因为你的新ngFor循环将指向这个数组,我们必须捕获它们。步骤3。迭代抛出所有键,并将每个键推送到您创建的数组中。这是代码中的样子。

    // Evil response in a variable. Here are all my vehicles.let evilResponse = {"car" :{"color" : "red","model" : "2013"},"motorcycle":{"color" : "red","model" : "2016"},"bicycle":{"color" : "red","model" : "2011"}}// Step 1. Get all the object keys.let evilResponseProps = Object.keys(evilResponse);// Step 2. Create an empty array.let goodResponse = [];// Step 3. Iterate throw all keys.for (prop of evilResponseProps) {goodResponse.push(evilResponseProps[prop]);}

这是原始帖子的链接。https://medium.com/@Papaponmx/循环覆盖对象属性

对象在实现. next()方法时成为迭代器

const james = {name: 'James',height: `5'10"`,weight: 185,
[Symbol.iterator]() {let properties = []for (let key of Object.keys(james)) {properties.push(key);}
index = 0;return {next: () => {let key = properties[index];let value = this[key];let done = index >= properties.length - 1;index++;return {key,value,done};}};}
};

const iterator = james[Symbol.iterator]();
console.log(iterator.next().value); // 'James'console.log(iterator.next().value); // `5'10`console.log(iterator.next().value); // 185

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]) })

如果您只想迭代属性,请使用上面的答案之一,但是如果您想迭代包括函数在内的所有内容,那么您可能需要使用Object.getOwnProperties tyNames(obj)

for (let o of Object.getOwnPropertyNames(Math)) {console.log(o);}

我有时使用它来快速测试具有简单输入和输出的对象上的所有函数。

  • 单级缩进
  • 单套括号
  • 最高的浏览器兼容性
  • hasOwnProperty安全

var p = {"p1": "value1", "p2": "value2", "p3": "value3"};
for (var key in p) if (p.hasOwnProperty(key)) {var value = p[key];console.log(key, value);}

    var p =[{"username":"ordermanageadmin","user_id":"2","resource_id":"Magento_Sales::actions"},{"username":"ordermanageadmin_1","user_id":"3","resource_id":"Magento_Sales::actions"}]for(var value in p) {for (var key in value) {if (p.hasOwnProperty(key)) {console.log(key + " -> " + p[key]);}}}

从ES06开始,您可以使用数组获取对象的值

let arrValues = Object.values( yourObject) ;

它返回对象值的数组,而不是从原型中提取值!!

MDN DOCSObject.values()

和钥匙(在我面前已经回答了)

let arrKeys   = Object.keys(yourObject);

前言:

  • 对象属性可以是 自己的(该属性位于对象本身上)或 继承的(不在对象本身上,而在其原型之一上)。
  • 对象属性可以是 数不胜数无法计数。大量的属性枚举/数组中没有包含不可枚举的属性。
  • 属性名称可以是字符串或符号。名称为符号的属性在大量的属性枚举/数组中被省略。

在2018年,循环遍历对象属性的选项如下(下面列出了一些示例) :

  1. 一个循环结构,循环遍历对象的 数不胜数属性的名称,包括名称为字符串的继承属性
  2. Object.keys [ MDN规格] & mdash; 一个函数,提供一个对象名称为字符串的 自己的数不胜数属性的名称数组。
  3. 一个函数,提供对象的 自己的数不胜数属性的 价值观数组。
  4. Object.entries [ MDN规格] & mdash; 一个函数,提供一个对象的 自己的数不胜数属性的名称 还有值的数组(数组中的每个条目都是一个 [name, value]数组)。
  5. Object.getOwnPropertyNames [ MDN规格] & mash; 一个函数,提供一个对象名为字符串的 自己的属性(甚至是非可枚举属性)的名称数组。
  6. Object.getOwnPropertySymbols [ MDN规格] & mash; 一个函数,提供一个对象的 自己的属性(甚至是非可枚举属性)的名称的数组,这些属性的名称是符号。
  7. Reflect.ownKeys [ MDN规格] & mash; 一个函数,提供对象的 自己的属性(甚至是不可枚举的属性)的名称的数组,不管这些名称是字符串还是符号。
  8. 如果你想要一个对象属性的 所有,包括不可枚举的继承属性,你需要使用一个循环和 Object.getPrototypeOf[ MDN规格] ,并在原型链中的每个对象上使用 Object.getOwnPropertyNamesObject.getOwnPropertySymbolsReflect.ownKeys(例如在这个答案的底部)。

对于除 for-in之外的所有类型,您将在数组上使用某种循环结构(forfor-offorEach等)。

例子:

返回文章页面

// 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}`);
}

返回文章页面

// 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}`);
}

返回文章页面

// 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}`);
}

返回文章页面

// 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}`);
}

返回文章页面

// 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}`);
}

返回文章页面

// 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.entries()功能:

var p = {
"p1": "value1",
"p2": "value2",
"p3": "value3"
};


for (var i in Object.entries(p)){
var key = Object.entries(p)[i][0];
var value = Object.entries(p)[i][1];
console.log('key['+i+']='+key+' '+'value['+i+']='+value);
}

这就是如何循环遍历 javascript 对象并将数据放入表中的方法。

<body>
<script>
function createTable(objectArray, fields, fieldTitles) {
let body = document.getElementsByTagName('body')[0];
let tbl = document.createElement('table');
let thead = document.createElement('thead');
let thr = document.createElement('tr');


for (p in objectArray[0]){
let th = document.createElement('th');
th.appendChild(document.createTextNode(p));
thr.appendChild(th);
    

}
 

thead.appendChild(thr);
tbl.appendChild(thead);


let tbdy = document.createElement('tbody');
let tr = document.createElement('tr');
objectArray.forEach((object) => {
let n = 0;
let tr = document.createElement('tr');
for (p in objectArray[0]){
var td = document.createElement('td');
td.appendChild(document.createTextNode(object[p]));
tr.appendChild(td);
n++;
};
tbdy.appendChild(tr);
});
tbl.appendChild(tbdy);
body.appendChild(tbl)
return tbl;
}


createTable([
{name: 'Banana', price: '3.04'}, // k[0]
{name: 'Orange', price: '2.56'},  // k[1]
{name: 'Apple', price: '1.45'}
])
</script>

您还可以使用 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]}`)
}
}

使用 为了... 为了..循环

 var p = {
"p1": "value1",
"p2": "value2",
"p3": "value3"
};
for (let key of Object.keys(p)){
console.log(`key: ${key} & value: ${p[key]}`)
}

Object.keysObject.valueObject.entry一起使用 为每个()

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 对象上循环的一个好方法是使用 Object.keysObject.entries和使用 map函数。如下:

// assume items:


const items = {
first: { name: 'phone', price: 400 },
second: { name: 'tv', price: 300 },
third: { name: 'sofa', price: 250 },
};

对于循环和显示一些用户界面的 ReactJS行为如下:

~~~
<div>
{Object.entries(items).map(([key, ({ name, price })]) => (
<div key={key}>
<span>name: {name}</span>
<span>price: {price}</span>
</div>
))}
</div>

实际上,我使用了两次解构赋值,一次用于获取 key,一次用于获取 nameprice

表演

今天,我在 Chrome v80.0,Safari v13.0.5和 Firefox 73.0.1上对所选的解决方案进行测试,在 MacOs High Sierra v10.13.6上

结论

  • 基于 for-in(A,B)的解决方案对于大小对象的所有浏览器都是快速(或最快)的
  • 令人惊讶的是 for-of(H)解决方案是快速的铬对小和大的对象
  • 基于显式索引 i(J,K)的解决方案在所有浏览器上对于小对象都相当快(对于大对象,Firefox 也很快,但是在其他浏览器上是中等快)
  • 基于迭代器(D,E)的解决方案是最慢的,不推荐使用
  • 解决方案 C 对于大型对象是慢速的,对于小型对象是中等-慢速的

enter image description here

细节

性能测试进行了

  • 小对象-有3个字段-您可以执行测试在您的机器 给你
  • ‘ big’对象-有1000个字段-您可以在您的机器 给你上执行测试

下面的片段展示了使用过的解决方案

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

And here are result for small objects on chrome

enter image description here

单行代码和更易读的代码可以. 。

Object.entries(myObject).map(([key, value]) => console.log(key, value))
Object.entries(myObject).map(([key, value]) => console.log(key, value))

你可以这样试试。myObject将是 {name: "", phone: ""}等等,这将生成键和值。键是 namephone,值是 dog123123

例子 {name: "dog"}

这里的键是 name,值是 dog

  1. 使用 为了... 进去和 < a href = “ https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global _ Objects/Object/hasOwnProperty”rel = “ norefrer”> Object hasOwnProperty

        var p = {
    "p1": "value1",
    "p2": "value2",
    "p3": "value3"
    };
    
    
    for (var key in p) {
    if (p.hasOwnProperty(key)) {
    console.log(key, ' : ', p[key]);
    }
    }

  2. 使用 为了... 为了..和 < a href = “ https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global _ Objects/Object/keys”rel = “ norefrer”> Object key

        var p = {
    "p1": "value1",
    "p2": "value2",
    "p3": "value3"
    };
    
    
    for (var key of Object.keys(p)) {
    console.log(key, " : ", p[key])
    }

  3. 使用 对象键和 < a href = “ https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global _ Objects/Array/forEach”rel = “ noReferrer”> for each

        var p = {
    "p1": "value1",
    "p2": "value2",
    "p3": "value3"
    };
    
    
    Object.keys(p).forEach(function(key) {
    console.log(key, ' : ', p[key]);
    });

  4. 使用 为了... 为了..和 < a href = “ https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global _ Objects/Object/entry”rel = “ noReferrer”> Object 条目

        var p = {
    "p1": "value1",
    "p2": "value2",
    "p3": "value3"
    };
    
    
    for (let [key, value] of Object.entries(p)) {
    console.log(key, ' : ', value);
    }

  5. 使用 对象条目和 < a href = “ https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global _ Objects/Array/forEach”rel = “ noReferrer”> for each

        var p = {
    "p1": "value1",
    "p2": "value2",
    "p3": "value3"
    };
    
    
    Object.entries(p).forEach(([key, value]) => console.log(key, ' : ', value));

var p = {
"p1": "value1",
"p2": "value2",
"p3": "value3"
};


var myMap = new Map( Object.entries(p) );


for ( let [k, v] of myMap.entries() ) {


console.log( `${k}: ${v}` )
  

}
<h3>ECMAScript 2017</h3>
<p><b>Object.entries()</b> makes it simple to convert <b>Object to Map</b>:</p>

有两个选择:

  1. 你可以使用 for..in

var p = {
"p1": "value1",
"p2": "value2",
"p3": "value3"
};


for (const item in p) {
console.log(`key = ${item}, value = ${p[item]}`);
}

  1. 还可以调用 Object.entries()来创建具有所有可枚举属性的数组。然后你可以使用 mapforeach或者 for..of来循环

var p = {
"p1": "value1",
"p2": "value2",
"p3": "value3"
};




Object.entries(p).map(item => {
console.log(item)
})

var p = {
"p1": "value1",
"p2": "value2",
"p3": "value3"
};




Object.entries(p).forEach(item => {
console.log(item)
})

var p = {
"p1": "value1",
"p2": "value2",
"p3": "value3"
};




for (const item of Object.entries(p)) {
console.log(item)
}

更多关于 Object.entries()可以找到 给你

将对象传递到 Object.keys()。这将返回一个包含对象中所有键的数组。然后可以使用 map循环遍历数组。使用 obj[key],其中 obj是您的对象,key是映射迭代中的当前值,您可以获得该键/属性的值。

const obj = { name: "Jane", age: 50 };


Object.keys(obj).map( key => {
console.log(key, obj[key]);
});

你可以使用我的库 monadic-objects,它的设计目的是简化对象的修改,使它的行为像数组一样:

p.forEach((key, value) => console.log(key, value))

安装: npm i monadic-objects

这个图书馆还包括方法:

  • map
  • filter
  • every
  • some

有关更多信息,请参见 自述

最接近 python 枚举函数的解决方案是:

for key, value in enumerate(object):
# Do something

Object.entries()for-of循环的组合:

for(let [key, value] of Object.entries(object)) {
// Do something
}

let object = {
key1: "value1",
key2: "value2",
key3: "value3",
key4: "value4",
key5: "value5"
};


for(let [key, value] of Object.entries(object)) {
console.log(`${key} -> ${value}`);
}