如何循环或枚举 JavaScript 对象?

Posted

技术标签:

【中文标题】如何循环或枚举 JavaScript 对象?【英文标题】:How do I loop through or enumerate a JavaScript object? 【发布时间】:2010-10-15 15:23:55 【问题描述】:

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

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

现在我想遍历所有p 元素(p1p2p3...)并获取它们的键和值。我该怎么做?

如有必要,我可以修改 JavaScript 对象。我的最终目标是遍历一些键值对,如果可能的话,我想避免使用eval

【问题讨论】:

【参考方案1】:
for(key in p) 
  alert( p[key] );

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

【讨论】:

当使用这样的 for 循环时,key 只会采用索引值,因此只会提醒 0、1、2 等...您需要访问 p[key] . 这是JavaScript中最慢的数组迭代方法。你可以在你的电脑上查看这个 - Best way to iterate over Arrays in JavaScript @Pencroff:问题在于问题不在于循环遍历数组... ;) 这是我在***上不明白的。理查德给出了正确的答案,他是第一个给出这个答案的人,但他没有得到任何+1? @Bryan var p = "p1":"q","p2":"w"; for(key in p) alert( key ); 在警报中弹出“p1”和“p2”,那有什么问题??? 我认为主要区别在于质量:其他答案不仅说明如何,还说明注意事项(例如原型)以及如何处理这些注意事项。恕我直言,其他答案比我的好:)。【参考方案2】:

你可以像这样迭代它:

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

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

【讨论】:

这是重复的,甚至不完全正确。您需要检查 hasOwnProperty 以使其正常工作 我最初根据上述评论对此表示反对,直到我意识到这个答案是第一位的,因此不是“重复的”。它可能不完整,但在许多情况下都可以正常工作。【参考方案3】:

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

这里是 sn-p:

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

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

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

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

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

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

【讨论】:

在 javascript 中,每个对象都有一堆具有元信息的内置键值对。当您遍历对象的所有键值对时,您也在遍历它们。 hasOwnPropery() 过滤掉这些。 实际上,For...in 并没有被弃用。 For each...in 是。但我真的很喜欢archaeologists这个词……我得开始用它了。 如何添加循环的值?谢谢 (for..in) 用于对象,(for.. of) 用于数组 感谢您的简单回答。它节省了我的时间。【参考方案4】:

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

【讨论】:

这比 levik 的解决方案要好,因为它允许主逻辑只有一个嵌套循环,而不是两个;使代码更易于阅读。虽然我会松开 continue 周围的括号;它们是多余的。 我不会亲自删除 ,因为没有它们的if 会让人有点不清楚if 的一部分是什么,什么不是。但我想这只是一个意见问题:) 是的,我更喜欢保留 ,主要是为了避免在以后需要在if 范围内添加一些内容时造成混淆。 阅读我之前的评论,我意识到我没有使用正确的术语,因为我说的是“if scope”;但请记住,JavaScript 仅具有函数作用域。所以我真正的意思是“如果阻止”。 “很遗憾,hasOwnProperty 是一种方法,而不是运算符,因此在任何对象中,它都可以替换为不同的函数,甚至是不是函数的值”【参考方案5】:

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

【讨论】:

为什么标准没有提供Object.forEach(obj, function (value, key) ...)? :( 当然obj.forEach(function...) 会更短并补充Array.prototype.forEach,但这会冒着让对象定义自己的forEach 属性的风险。我想Object.keys 防止回调修改对象的键。【参考方案6】:

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

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

【讨论】:

JSON 对象是否干净无关紧要。如果在任何其他时间某些代码在Object.prototype 上设置了一个属性,那么它将被for..in 枚举。如果你确定你没有使用任何库,那么你不需要调用hasOwnProperty Object.create(null)创建可以完全干净【参考方案7】:

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>

【讨论】:

【参考方案8】:

通过 prototypeforEach() 应该跳过 prototype 链 属性:

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 函数可能会在一定程度上降低风险。【参考方案9】:

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

如今,许多知名的 JavaScript 库都提供了自己的方法来迭代集合,例如 arraysobjects类数组对象 .这些方法使用方便,完全兼容任何浏览器。

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

    $.each(obj, function(key, value) 
        console.log(key, value);
    );
    

    Underscore.js 中,您可以找到方法 _.each(),它遍历元素列表,将每个元素依次生成给提供的函数(注意 中的参数顺序iteratee 函数!):

    _.each(obj, function(value, key) 
        console.log(key, value);
    );
    

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

    _.forIn(obj, function(value, key) 
        console.log(key, value);
    );
    

    _.forIn() 迭代对象的拥有和继承 可枚举属性,而_.forOwn() 仅迭代对象的拥有 属性(基本上检查hasOwnProperty功能)。对于简单的对象和对象字面量,这些方法中的任何一个都可以正常工作。

通常所有描述的方法对任何提供的对象都有相同的行为。除了使用本机 for..in 循环通常会更快 比任何抽象,例如 jQuery.each(),这些方法更容易使用,需要更少的编码并提供更好的错误处理。

【讨论】:

获取值:$.each(obj, function (key, value) console.log(value.title); ); 下划线和jquery如何改变参数很有趣:)【参考方案10】:

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

Extend Implementations Object keys iteration object literal iteration

您可以在 Kangax's compat table 上查看浏览器支持

对于旧浏览器,您有 simple 和 full polyfill

UPD:

perfjs.info 上此问题中所有最流行案例的性能比较:

object literal iteration

【讨论】:

确实,我只是想发布这个方法。但你打败了我:(【参考方案11】:

因为提问者的['最终目标是循环一些键值对'],最后不寻找循环。

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

【讨论】:

不!他写了“现在我想遍历所有 p 元素”,所以他真的需要一个像他接受的答案一样的循环。【参考方案12】:

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

【讨论】:

【参考方案13】:

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 毫秒。

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


// OR 
let map = new Map([
    [false, 'no'],
    [true,  'yes'],
]);
map.forEach((value, key) => 
    console.log(key, value);
);

【讨论】:

如果您不想放弃 符号,您仍然可以使用 of without creating Maps【参考方案14】:

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

【讨论】:

【参考方案15】:

如果您还想遍历 non-enumerable properties,您可以使用 Object.getOwnPropertyNames(obj) 返回直接在给定对象上找到的所有属性(可枚举或不可枚举)的数组。

var obj = Object.create(, 
  // non-enumerable property
  getFoo: 
    value: function()  return this.foo; ,
    enumerable: false
  
);

obj.foo = 1; // enumerable property

Object.getOwnPropertyNames(obj).forEach(function (name) 
  document.write(name + ': ' + obj[name] + '<br/>');
);

【讨论】:

这太棒了,感谢您发布此答案。我需要自省 Error 对象,但无法在循环或 _.forIn(err) 调用中获取属性。使用Object.getOwnPropertyNames(err) 允许我访问Error 的所有我以前无法访问的部分。谢谢!【参考方案16】:

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

// before ES2015
for(var key of elements)
  console.log(elements[key]);



// ES2015
for(let element of elements)
  console.log(element);

希望这对某人有所帮助。

【讨论】:

不仅没有帮助,而且不准确。 For...of 仅在 elements 定义了迭代器时才有效。数组、集合和映射都是如此,但对象却不是。 you can actually make this work, @EvanCarroll【参考方案17】:

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

在这成为新标准之前,旧方法仍然可以使用,但在流行的库中也有替代方法,甚至lightweight alternatives 用于那些不使用任何这些库的人。

【讨论】:

你能提供这个工作的小提琴吗?这是我的尝试。 jsfiddle.net/abalter/sceeb211 @abalter 抱歉,我意识到我的代码中有错字。我修复了它并在这里更新了你的 JsFiddle:jsfiddle.net/sceeb211/2 我正在使用 chrome 并收到 Uncaught TypeError: Object.entries is not a function。是不是还没有在 chrome 中实现? @abalter 是的。确保您拥有 Chrome 版本 51,并且您已按照我的编辑和 Jsfiddle cmets 中的说明启用了该标志。您可以在这里查看详细信息:developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/… 抱歉,我错过了关于国旗的内容。我发现它还没有完全实现。【参考方案18】:

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

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

您不能只使用for...ofObject,因为它不是迭代器,而for...index.forEach() 使用Object.keys() 是丑陋/低效的。 我很高兴大多数人都避免使用for...in(无论是否检查.hasOwnProperty()),因为这也有点混乱,所以除了我上面的回答之外,我在这里说...


你可以让普通的对象关联迭代!行为就像 Maps 直接使用花哨的 for...ofDEMO 在 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]);

事实上,有了这个 shim,如果你仍然想利用 Map 的其他功能(而不是全部填充)但仍然想使用整洁的对象表示法,因为对象现在是可迭代的,你现在可以制作一个 Map从它!

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

对于那些不喜欢 shim 或一般不喜欢 prototype 的人,请随意在 window 上创建函数,然后将其称为 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))

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

欢迎来到未来。

【讨论】:

Caseinpoint。只要人们向下滚动并发现它有帮助,这就是最重要的。通常是我尝试做某事,不喜欢我在网上看到的东西,最终弄明白了,然后我回来分享。很好的文档,在搜索我完全忘记的东西之前,我实际上已经找到了自己的答案! @HelpMe***MyOnlyHope 就我个人而言,我不喜欢修改我自己没有定义的对象的原型。 @JanusTroelsen 您是否阅读了整个答案? 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 这样的变量名,以强调魔法仍然适用于这些类型)。你检查过演示吗?什么不适合你,@noɥʇʎԀʎzɐɹƆ? (P.S. 你的 SE 头像是老板)【参考方案19】:

如果有人需要循环遍历 arrayObjects with condition

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

【讨论】:

【参考方案20】:

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

【讨论】:

这对我来说看起来完全多余/不需要。您会将它添加到系统中的每个对象中吗?我认为提供迭代器的目的是让您可以执行“for(const [k, v] of myObject)”。它只是看起来像额外的代码,提供的额外价值很少。【参考方案21】:

考虑到 ES6,我想添加我自己的糖勺,并提供另一种方法来迭代对象的属性。

由于普通的 JS 对象不是开箱即用的 iterable,因此我们无法使用 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 names
  let 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 book
Me
3

或者如果您知道 ES6 generators 的强大功能,那么您当然可以使上面的代码更短。

book[Symbol.iterator] = function *()

  let properties = Object.keys(this);
  for (let p of properties)
    yield this[p];
  


当然,您可以通过在prototype 级别上使Object 可迭代来将此类行为应用于所有对象。

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

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

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

或者你可以使用destructuring赋值:

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

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

【讨论】:

我发现代码会生成值但没有键。是否可以用键迭代值? 是的,你可以。只需返回“yield [key, obj[key]];”从您的生成器函数中,然后像下面这样使用它“for(let [ key, value ] of ) ”【参考方案22】:

在 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 的能力很重要!

【讨论】:

自定义对象迭代器调用由Object.keys()生成并分配在内存中的数组的内置数组迭代器......酷!【参考方案23】:

你可以给所有对象添加一个简单的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”方法的人:

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)通常被认为是一种反模式,因为它很容易与其他代码发生冲突。所以伤口建议这样做。【参考方案24】:

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

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

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

    // 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/looping-over-object-properties-with-ngfor-in-angular-869cd7b2ddcc

【讨论】:

【参考方案25】:

对象在实现 .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

【讨论】:

【参考方案26】:

Object.keys() 方法返回给定对象自己的可枚举属性的数组。阅读更多关于它的信息here

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

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

【讨论】:

【参考方案27】:

这是另一种遍历对象的方法。

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


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

【讨论】:

这很酷,但是对于大型对象,for 方法可能更高效。【参考方案28】:

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

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

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

【讨论】:

我不知道为什么它被否决了,但是现在看这个是完美的,因为在 javascript 中,“方法”只是 JS let test = function() this.method = () =&gt; ; console.log(new test()); 中的对象上的属性@【参考方案29】: 单级缩进 单组括号 最高的浏览器兼容性 hasOwnProperty safe

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

【讨论】:

【参考方案30】:

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

【讨论】:

json = ["key1":"value1","key2":"value2","key1":"value3","key2":"value4"] for (var i = 0; i &lt; json.length; i++) for (var key in json[i]) if (json[i].hasOwnProperty(key)) console.log(key + " -&gt; " + json[i][key]);

以上是关于如何循环或枚举 JavaScript 对象?的主要内容,如果未能解决你的问题,请参考以下文章

javascript JavaScript中的枚举和词典,循环/枚举javascript对象

[JavaScript]_[初级]_[关于forin或for...in循环语句的用法]

[JavaScript]_[初级]_[关于forin或for...in循环语句的用法]

[JavaScript]_[初级]_[关于forin或for...in循环语句的用法]

如何将 List<string> 分配给 JavaScript 数组或可枚举对象

如何让对象属性不可配置或枚举