如何循环或枚举JavaScript对象?

时间:2009-03-26 06:01:48

标签: javascript loops each

我有一个类似以下的JavaScript对象:

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

现在,我想遍历所有p元素(p1p2p3 ...)并获取其键和值。我怎么能这样做?

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

41 个答案:

答案 0 :(得分:3960)

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

以下是摘录:

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

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

答案 1 :(得分:863)

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

答案 2 :(得分:324)

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

答案 3 :(得分:246)

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

现在许多知名的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功能)。对于简单对象和对象文字,这些方法中的任何一种都可以正常工作。

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

答案 4 :(得分:49)

在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's compat table

上看到的浏览器支持

对于旧浏览器,您有simplefull polyfill

<强> UPD:

perfjs.info

中此问题中所有最常见案例的效果比较

object literal iteration

答案 5 :(得分:45)

您可以像以下一样迭代它:

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

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

答案 6 :(得分:36)

前言:

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

在2018年,您可以使用以下选项遍历对象的属性(某些示例在列表后面):

  1. for-in [MDNspec] —一种循环结构,循环遍历对象的 enumerable 属性名称,包括名称为字符串的继承人
  2. Object.keys [MDNspec] —提供对象的 own ,<字符串形式的em> enumerable 属性。
  3. Object.values [MDNspec] —提供对象的数组的函数可枚举属性。
  4. Object.entries [MDNspec] —一种函数,提供对象<的名称​​和值的数组em> own ,可枚举属性(数组中的每个条目都是一个[name, value]数组)。
  5. Object.getOwnPropertyNames [MDNspec] —提供对象的 own 属性名称数组的函数(甚至是不可枚举的名称)都是字符串。
  6. Object.getOwnPropertySymbols [MDNspec] —提供对象的 own 属性名称数组的函数(甚至是不可枚举的符号)。
  7. Reflect.ownKeys [MDNspec] —提供对象的 own 属性名称数组的函数(甚至是不可枚举的名称),无论这些名称是字符串还是符号。
  8. 如果要所有一个对象的属性,包括不可枚举的继承属性,则需要使用循环和Object.getPrototypeOf [MDNspec ],并在原型链中的每个对象上使用Object.getOwnPropertyNamesObject.getOwnPropertySymbolsReflect.ownKeys(示例在此答案的底部)。

对于除for-in以外的所有变量,您将在数组上使用某种循环构造(forfor-offorEach等)。 / p>

示例:

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

答案 7 :(得分:26)

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

答案 8 :(得分:19)

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

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

答案 9 :(得分:19)

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

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

答案 10 :(得分:19)

通过原型 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

答案 11 :(得分:17)

性能

今天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(J,K)的解决方案在所有小型对象浏览器中都非常快(对于firefox,对于大型对象也是如此,而在其他浏览器中为中等)
  • 基于迭代器(D,E)的解决方案最慢,不推荐使用
  • 对于大型物体,解决方案C较慢;对于小型物体,解决方案C较慢

enter image description here

详细信息

针对

进行了性能测试
  • 具有3个字段的小对象-您可以在计算机HERE上进行测试
  • “大”对象-具有1000个字段-您可以在计算机HERE上进行测试

下面的摘要介绍了已使用的解决方案

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

这是镀铬小物体的结果

enter image description here

答案 12 :(得分:16)

有趣的是,这些答案中的人都触及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()然后;

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

欢迎来到未来。

答案 13 :(得分:12)

  

Object.keys(obj):Array

     

检索所有可枚举的自有(非继承)属性的所有字符串值。

因此,它通过使用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);
});

答案 14 :(得分:11)

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

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


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

答案 15 :(得分:11)

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>

答案 16 :(得分:10)

您还可以使用Object.keys()并如下遍历对象键来获取值:

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

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

答案 17 :(得分:8)

Object.keys()方法返回给定对象自己的可枚举属性的数组。详细了解here

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

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

答案 18 :(得分:7)

您可以向所有对象添加一个简单的 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发生冲突,可以使用您的唯一名称命名。

答案 19 :(得分:6)

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

答案 20 :(得分:5)

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

答案 21 :(得分:5)

使用纯JavaScript时,循环可能非常有趣。似乎只有ECMA6(New 2015 JavaScript规范)才能控制循环。不幸的是,当我写这篇文章时,浏览器和流行的集成开发环境(IDE)仍然在努力完全支持新的铃声和口哨。

这里是一个JavaScript对象循环在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;
  }
}

另外,我知道这个问题超出了这个问题但是在2011年,ECMAScript 5.1仅为Arrays添加了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

答案 22 :(得分:4)

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

var obj = {a : 1};
for(var key in obj){
    //obj.hasOwnProperty(key) is not needed.
    console.log(key);
}
//then check if anybody has messed the native object. Put this code at the end of the page.
for(var key in Object){
    throw new Error("Please don't extend the native object");
}

答案 23 :(得分:4)

在一个可枚举的JavaScript对象上循环的好方法(对于ReactJS来说可能是很棒的和普遍的)是使用Object.keysObject.entriesmap函数。如下所示:

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

答案 24 :(得分:4)

自ES06起,您可以使用

将对象的值获取为数组

let arrValues = Object.values( yourObject) ;

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

MDN DOCS Object.values()

和键(在这里已经在我前面回答了)

let arrKeys   = Object.keys(yourObject);

答案 25 :(得分:4)

for-of上使用Object.keys()

赞:

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

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

答案 26 :(得分:4)

在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的功能!

答案 27 :(得分:4)

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

由于普通的JS对象不是iterable,因此我们无法使用"mappings" : { "_default_" : { "_all" : {"enabled" : true, "omit_norms" : true}, "dynamic_templates" : [ { "ID" : { "match" : "ID", "mapping" : { "type" : "string", "index" : "not_analyzed" } } }, { "Name" : { "match" : "Name", "mapping" : { "type" : "string", "index" : "not_analyzed" } } }, { "ip" : { "match" : "ip", "mapping" : { "type" : "ip", "index" : "not_analyzed" } } }, { "string_fields" : { "match" : "*", "mapping" : { "type" : "float", "index" : "not_analyzed" } } }], "properties" : { "@timestamp" : { "type" : "date" } } } } } } } 循环来迭代其内容。但没有人可以阻止我们使其可迭代

我们有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 };
}

或者如果您了解ES6 generators的强大功能,那么您肯定可以使上面的代码更短。

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

当然,您可以在book[Symbol.iterator] = function *(){ let properties = Object.keys(this); for (let p of properties){ yield this[p]; } } 级别Object进行迭代,对所有对象应用此类行为。

prototype

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

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

或者您可以使用destructuring作业:

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

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

答案 28 :(得分:3)

如果您想迭代 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/>');
});

答案 29 :(得分:3)

如果有人需要循环 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");
      }
   }
}

答案 30 :(得分:3)

在最新的ES脚本中,您可以执行以下操作:

Object.entries(p);

答案 31 :(得分:2)

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

答案 32 :(得分:2)

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

循环中使用

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

使用 for 循环

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

forEach() Object.keys Object.values Object.entries

一起使用

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

答案 33 :(得分:1)

这是循环遍历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>

答案 34 :(得分:1)

实现.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

答案 35 :(得分:1)

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

答案 36 :(得分:0)

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

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

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

答案 37 :(得分:0)

如果您的应用程序是在创建字符串,则可以与Object.keys,implode和.map数组方法完美结合。例如,如果我们有一个

之类的json对象,
var data = {
    key1: 10,
    key2: 'someString',
    key3: 3000
}

..我们希望生成 “值是key1 = 10,key2 = someString,key3 = 3000。”

我们可以在单行代码中完成此操作:

var str = `The values are ${implode(', ', Object.keys(data).map(function(key){return `${key} = ${data[key]}`}))}.`;

Implode将数组折叠为字符串,并在元素之间插入定界符(第一个参数); .map遍历数组返回一个数组,其他答案对Object.keys进行了很好的阐述。

答案 38 :(得分:-1)

  • 单级缩进
  • 单组括号
  • 最高浏览器兼容性
  • hasOwnProperty safe

&#13;
&#13;
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);
}
&#13;
&#13;
&#13;

答案 39 :(得分:-2)

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

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


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

希望这有助于某人。

答案 40 :(得分:-5)

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

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