如何遍历或枚举JavaScript对象?

我有一个如下的JavaScript对象: var p = { "p1": "value1", "p2": "value2", "p3": "value3"}; 现
摘要由CSDN通过智能技术生成

我有一个如下的JavaScript对象:

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

现在,我想遍历所有p元素( p1p2p3 ...),并获取它们的键和值。 我怎样才能做到这一点?

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


#1楼

通过原型foreach(),它应跳过原型链属性:

Object.prototype.each = function(f) {
    var obj = this
    Object.keys(obj).forEach( function(key) { 
        f( key , obj[key] ) 
    });
}


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

#2楼

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

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

  1. 如果使用jQuery ,则可以使用jQuery.each()方法。 它可以用来无缝地遍历对象和数组:

     $.each(obj, function(key, value) { console.log(key, value); }); 
  2. Underscore.js你可以找到方法_.each()它遍历元素的列表,每个收益依次为提供的功能(要注意在iteratee函数参数的顺序!):

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

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

    _.forIn()遍历对象的自身和继承的可枚举属性,而_.forOwn()仅遍历对象的自身属性(基本上检查hasOwnProperty函数)。 对于简单的对象和对象文字,这些方法中的任何一种都可以正常工作。

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


#3楼

在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的compat表上看到的浏览器支持

对于旧的浏览器,您可以使用简单完整的 polyfill

UPD:

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

对象文字迭代


#4楼

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

#5楼

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


#6楼

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

#7楼

如果还想遍历不可枚举的属性

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值