如何循环或枚举 JavaScript 对象?

发布于 2024-07-15 11:55:46 字数 227 浏览 6 评论 0原文

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

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

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

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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(30

挥剑断情 2024-07-22 11:55:47

Object.keys()上使用for-of

例如:

let object = {
  "key1": "value1",
  "key2": "value2",
  "key3": "value3"
};

for (let key of Object.keys(object)) {
  console.log(key + " : " + object[key])
}

Using a for-of on Object.keys()

Like:

let object = {
  "key1": "value1",
  "key2": "value2",
  "key3": "value3"
};

for (let key of Object.keys(object)) {
  console.log(key + " : " + object[key])
}

夜夜流光相皎洁 2024-07-22 11:55:47

您还可以使用 Object.keys() 并迭代对象键,如下所示以获取值:

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

Object.keys(p).forEach((key)=> {
 console.log(key +' -> '+ p[key]);
});

You can also use Object.keys() and iterate over the object keys like below to get the value:

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

Object.keys(p).forEach((key)=> {
 console.log(key +' -> '+ p[key]);
});

靖瑶 2024-07-22 11:55:47
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>

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>

夏末 2024-07-22 11:55:47

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 毫秒。
  • for...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);
});

Object.keys(obj) : Array

retrieves all string-valued keys of all enumerable own (non-inherited) properties.

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:

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

In my Firefox I have following results

  • Object.keys approach took 40.21101451665163 milliseconds.
  • for...in/hasOwnProperty approach took 98.26163508463651 milliseconds.

PS. on Chrome the difference even bigger http://codepen.io/dsheiko/pen/JdrqXa

PS2: In ES6 (EcmaScript 2015) you can iterate iterable object nicer:

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

话少心凉 2024-07-22 11:55:47

在最新的 ES 脚本中,你可以这样做:

let p = {foo: "bar"};
for (let [key, value] of Object.entries(p)) {
  console.log(key, value);
}

In latest ES script, you can do something like this:

let p = {foo: "bar"};
for (let [key, value] of Object.entries(p)) {
  console.log(key, value);
}

飘落散花 2024-07-22 11:55:47

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

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

Object.keys(obj).map( key => {
    console.log(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 using map. Using obj[key] where obj is your object and key is the current value in the map iteration, you can get the value for that key/property.

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

Object.keys(obj).map( key => {
    console.log(key, obj[key]);
});
梦晓ヶ微光ヅ倾城 2024-07-22 11:55:47

只有没有依赖关系的 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
}

Only JavaScript code without dependencies:

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
}
逆夏时光 2024-07-22 11:55:47

Object.keys() 方法返回给定对象自己的可枚举属性的数组。 此处了解更多相关信息

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

Object.keys(p).map((key)=> console.log(key + "->" + p[key]))

The Object.keys() method returns an array of a given object's own enumerable properties. Read more about it here

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

Object.keys(p).map((key)=> console.log(key + "->" + p[key]))

无风消散 2024-07-22 11:55:47

这是迭代对象的另一种方法。

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


Object.keys(p).forEach(key => { console.log(key, p[key]) })

Here is another method to iterate through an object.

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


Object.keys(p).forEach(key => { console.log(key, p[key]) })

虚拟世界 2024-07-22 11:55:47

在 javascript 中迭代对象的多种方式

使用 for...in 循环

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

使用 for...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.keysObject.valuesObject.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}`)
})

Multiple way to iterate object in javascript

Using for...in loop

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

Using for...of loop

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

Using forEach() with 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}`)
})

泪痕残 2024-07-22 11:55:47

使用纯 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 中,您也需要启用此特殊标志才能使其工作:< 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:

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

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 confusing for loop. But the odd part is that this new forEach method does not support break 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:

for (let [key, value] of Object.entries(object)) {
    console.log(key); // This is the key;
    console.log(value); // This is the value;
}

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.

微凉 2024-07-22 11:55:47
Object.entries(myObject).map(([key, value]) => console.log(key, value))

你可以这样尝试。 myObject 将是 {name: "", Phone: ""} 如此这般,这将生成键和值。 所以这里的键是namephone,值就像dog123123

示例 {name: "dog"}

这里的键是 name,值是 dog

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

You can try like this. myObject will be {name: "", phone: ""} so and so, this will generate key and value. So key here is name, phone and value are like dog, 123123.

Example {name: "dog"}

Here key is name and value is dog.

简单 2024-07-22 11:55:47

您可以向所有对象添加一个简单的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
});

对于那些不喜欢“for ... in”的人-method:

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

You can add a simple forEach function to all objects, so you can automatically loop through any object:

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

For those people who don't like the "for ... in"-method:

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

Now, you can simple call:

p.forEach (function(key, value){
    console.log ("Key: " + key);
    console.log ("Value: " + value);
});

If you don't want to get conflicts with other forEach-Methods you can name it with your unique name.

靖瑶 2024-07-22 11:55:47

循环可枚举 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 上显示一些 UI,如下所示:

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

实际上,我使用解构赋值两次,一次用于获取 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 or Object.entries with using map function. like below:

// assume items:

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

For looping and show some UI on ReactJS act like below:

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

Actually, I use the destructuring assignment twice, once for getting key once for getting name and price.

找个人就嫁了吧 2024-07-22 11:55:47

在 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 拥有的功能很重要!

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:

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

[...p] //["p1", "p2", "p3"]

this will give the same result as using for...in es6 loop.

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

But its important to know the capabilities you now have using es6!

╭ゆ眷念 2024-07-22 11:55:47

我会这样做,而不是在每个 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");
}

I would do this rather than checking obj.hasOwnerProperty within every for ... in loop.

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");
}
捂风挽笑 2024-07-22 11:55:46

您可以使用 for- in 循环,如其他人所示。 但是,您还必须确保您获得的密钥是对象的实际属性,而不是来自原型。

这是片段:

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

for (var key in p) {
    if (p.hasOwnProperty(key)) {
        console.log(key + " -> " + p[key]);
    }
}

For-of 与 Object.keys() 替代方案:

var p = {
    0: "value1",
    "b": "value2",
    key: "value3"
};

for (var key of Object.keys(p)) {
    console.log(key + " -> " + p[key])
}

请注意 for- 的使用 而不是 for-in,如果不使用,它将在命名属性上返回未定义,并且 Object.keys() 确保仅使用对象自己的属性,而不使用整个原型链属性

使用新的对象。 Entry() 方法:

注意: Internet Explorer 本身不支持此方法。 您可以考虑为旧版浏览器使用 Polyfill。

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

for (const [key, value] of Object.entries(p)) {
  console.log(`${key}: ${value}`);
}

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:

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

for (var key in p) {
    if (p.hasOwnProperty(key)) {
        console.log(key + " -> " + p[key]);
    }
}

For-of with Object.keys() alternative:

var p = {
    0: "value1",
    "b": "value2",
    key: "value3"
};

for (var key of Object.keys(p)) {
    console.log(key + " -> " + p[key])
}

Notice the use of for-of instead of for-in, if not used it will return undefined on named properties, and Object.keys() ensures the use of only the object's own properties without the whole prototype-chain properties

Using the new Object.entries() method:

Note: This method is not supported natively by Internet Explorer. You may consider using a Polyfill for older browsers.

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

for (const [key, value] of Object.entries(p)) {
  console.log(`${key}: ${value}`);
}
箜明 2024-07-22 11:55:46

在 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...of

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

Under ECMAScript 5, you can combine Object.keys() and Array.prototype.forEach():

var obj = { first: "John", last: "Doe" };

Object.keys(obj).forEach(function(key) {
    console.log(key, obj[key]);
});

ECMAScript 6 adds for...of:

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

ECMAScript 8 adds Object.entries() which avoids having to look up each value in the original object:

Object.entries(obj).forEach(
    ([key, value]) => console.log(key, value)
);

You can combine for...of, destructuring, and Object.entries:

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

Both Object.keys() and Object.entries() iterate properties in the same order as a for...in loop but ignore the prototype chain. Only the object's own enumerable properties are iterated.

杀手六號 2024-07-22 11:55:46

你必须使用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
}

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:

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
}
温柔女人霸气范 2024-07-22 11:55:46

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

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

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

    $.each(obj, 函数(键, 值) { 
          控制台.log(键,值); 
      }); 
      
  2. Underscore.js 中,您可以找到方法 _.each(),它迭代元素列表,依次将每个元素生成提供的函数(注意 iteratee< 中参数的顺序/em> 函数!):

    _.each(obj, 函数(值, 键) { 
          控制台.log(键,值); 
      }); 
      

  3. < p>Lo-Dash 提供了多种迭代对象属性的方法。 基本 _.forEach() (或其别名 _.each ()) 对于循环对象和数组很有用,但是 (!) 具有 length 属性的对象被视为数组,为了避免这种行为,建议使用 _.forIn()_.forOwn() 方法(这些方法也有 value 参数在前):

    _.forIn(obj, 函数(值, 键) { 
          控制台.log(键,值); 
      }); 
      

    _.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.

  1. If you work with jQuery, you may use jQuery.each() method. It can be used to seamlessly iterate over both objects and arrays:

    $.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() iterates over own and inherited enumerable properties of an object, while _.forOwn() iterates only over own properties of an object (basically checking against hasOwnProperty 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 as jQuery.each(), these methods are considerably easier to use, require less coding and provide better error handling.

2024-07-22 11:55:46

前言:

  • 对象属性可以是自己的(该属性位于对象本身)或继承(不在对象本身上,而是在其原型之一上)。
  • 对象属性可以是可枚举不可枚举。 不可枚举的属性被排除在许多属性枚举/数组之外。
  • 属性名称可以是字符串或符号。 名称为 Symbols 的属性被排除在许多属性枚举/数组之外。

在 2018 年,循环访问对象属性的选项是(列表后面有一些示例):

  1. for-in [MDN, spec] — 循环结构,循环遍历对象的可枚举属性的名称,包括继承的属性,其名称为字符串
  2. Object.keys [MDN规范 ] — 一个函数,提供对象的自己可枚举属性(其名称为字符串)的名称数组。
  3. Object.values [MDN, spec] — 提供对象自己数组,可枚举属性。
  4. Object.entries [MDN, spec] — 提供对象的自身可枚举属性的名称​​和值数组(数组中的每个条目都是[name, value] 数组)。
  5. Object.getOwnPropertyNames [MDN, spec] — 提供对象的自己属性(甚至是不可枚举的属性)的名称数组,其名称是字符串。
  6. Object.getOwnPropertySymbols [MDN, spec] — 提供对象的自己属性(甚至是不可枚举的属性)的名称数组,其名称为 Symbols。
  7. Reflect.ownKeys [MDN, spec] — 提供对象自己的属性(甚至是不可枚举的属性)的名称数组,无论这些名称是字符串还是符号。
  8. 如果您想要对象的所有属性,包括不可枚举的继承属性,则需要使用循环和Object.getPrototypeOf [MDNspec] 并使用 Object.getOwnPropertyNamesObject.getOwnPropertySymbolsReflect.ownKeys< /code> 原型链中的每个对象(示例位于本答案的底部)。

除了 for-in 之外的所有这些,您都可以在数组上使用某种循环构造(forfor-of、<代码>forEach等)。

示例:

for-in

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

Preface:

  • Object properties can be own (the property is on the object itself) or inherited (not on the object itself, on one of its prototypes).
  • Object properties can be enumerable or non-enumerable. Non-enumerable properties are left out of lots of property enumerations/arrays.
  • Property names can be strings or Symbols. Properties whose names are Symbols are left out of lots of property enumerations/arrays.

Here in 2018, your options for looping through an object's properties are (some examples follow the list):

  1. for-in [MDN, spec] — A loop structure that loops through the names of an object's enumerable properties, including inherited ones, whose names are strings
  2. Object.keys [MDN, spec] — A function providing an array of the names of an object's own, enumerable properties whose names are strings.
  3. Object.values [MDN, spec] — A function providing an array of the values of an object's own, enumerable properties.
  4. 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).
  5. 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.
  6. 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.
  7. 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.
  8. If you want all of an object's properties, including non-enumerable inherited ones, you need to use a loop and Object.getPrototypeOf [MDN, spec] and use Object.getOwnPropertyNames, Object.getOwnPropertySymbols, or Reflect.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:

// 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 (with a for-of loop, but you can use any looping construct):

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

All properties, including inherited non-enumerable ones:

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

双马尾 2024-07-22 11:55:46

您可以像这样迭代它:

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

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

You can just iterate over it like:

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

Note that key will not take on the value of the property, it's just an index value.

撩人痒 2024-07-22 11:55:46

在 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 的兼容表

对于旧浏览器,您有 简单完整 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)

var keys = Object.keys(p),
    len = keys.length,
    i = 0,
    prop,
    value;
while (i < len) {
    prop = keys[i];
    value = p[prop];
    i += 1;
}

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

海未深 2024-07-22 11:55:46

今天的性能

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 对于大对象也很快,但在其他浏览器上中等快)
  • 基于迭代器 (D,E) 的解决方案是最慢的,不推荐
  • 解决方案 C 很慢对于大对象,中慢速对于小对象

在此处输入图像描述

详细信息

针对小对象执行了性能测试

  • - 有 3 个字段 - 您可以在您的机器上执行测试 此处
  • “大”对象 - 具有 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

以下是 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

  • solutions based on for-in (A,B) are fast (or fastest) for all browsers for big and small objects
  • surprisingly for-of (H) solution is fast on chrome for small and big objects
  • solutions based on explicit index i (J,K) are quite fast on all browsers for small objects (for firefox also fast for big ojbects but medium fast on other browsers)
  • solutions based on iterators (D,E) are slowest and not recommended
  • solution C is slow for big objects and medium-slow for small objects

enter image description here

Details

Performance tests was performed for

  • small object - with 3 fields - you can perform test on your machine HERE
  • 'big' object - with 1000 fields - you can perform test on your machine HERE

Below snippets presents used solutions

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

离笑几人歌 2024-07-22 11:55:46
for(key in p) {
  alert( p[key] );
}

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

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

Note: you can do this over arrays, but you'll iterate over the length and other properties, too.

乖乖 2024-07-22 11:55:46

由于 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 页面

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:

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

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.

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

You can find more about usage on
MDN page

无戏配角 2024-07-22 11:55:46

单行和更具可读性的代码可以是..

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

Single line and more readable code can be..

Object.entries(myObject).map(([key, value]) => console.log(key, value))
未蓝澄海的烟 2024-07-22 11:55:46

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

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

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:

for (var key in p) {
    console.log(key + ' => ' + p[key]);
    // key is key
    // value is p[key]
}
我只土不豪 2024-07-22 11:55:46

通过 prototypeforEach() ,它应该跳过 prototype chain 属性:

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

via prototype with forEach() which should skip the prototype chain properties:

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
枉心 2024-07-22 11:55:46

有趣的是,这些答案中的人们都触及了 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()),因为这也有点混乱,所以除了我的答案上面,我在这里想说的是...


你可以让普通的对象关联迭代! 行为就像 Map 一样,直接使用花哨的 for...of
DEMO 在 Chrome 和 FF 中工作(我假设仅限 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:'!'});

对于那些不喜欢填充或乱搞 prototype 的人,请随意在窗口上创建该函数,将其称为 getObjIterator() > then;

//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))

没有理由为什么那行不通。

欢迎来到未来。

It's interesting people in these answers have touched on both Object.keys() and for...of but never combined them:

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

You can't just for...of an Object because it's not an iterator, and for...index or .forEach()ing the Object.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 Maps with direct use of the fancy for...of
DEMO working in Chrome and FF (I assume ES6 only)

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

So long as you include my shim below:

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

Without having to create a real Map object that doesn't have the nice syntactic sugar.

var trueMap = new Map([['well', 'hello'], ['there', '!']]);
for (let pair of trueMap)
    console.log(pair[0] + ':' + pair[1]);

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!

//shown in demo
var realMap = new Map({well:'hello', there:'!'});

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;

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

Now you can just call it as an ordinary function, nothing else is affected

var realMap = new Map(getObjIterator({well:'hello', there:'!'}))

or

for (let pair of getObjIterator(ordinaryObject))

There's no reason why that wouldn't work.

Welcome to the future.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文