3332

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

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

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

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

4

43 回答 43

4917

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

这是片段:

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}`);
}
于 2009-03-26T06:12:13.807 回答
1267

在 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

于 2011-04-20T21:59:19.703 回答
366

您必须使用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
}
于 2009-03-26T06:12:16.960 回答
262

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

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

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

    $.each(obj, function(key, value) {
        console.log(key, value);
    });
    
  2. Underscore.js中,您可以找到 method _.each(),它遍历元素列表,将每个元素依次生成给提供的函数(注意iteratee函数中参数的顺序!):

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

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

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

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

于 2013-01-20T17:58:26.900 回答
64

前言:

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

在 2018 年,您可以选择循环遍历对象的属性(列表后面有一些示例):

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

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

例子:

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

于 2018-07-10T10:39:33.197 回答
58

你可以像这样迭代它:

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

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

于 2009-03-26T06:05:01.797 回答
56

在 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

升级版:

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

对象字面量迭代

于 2013-11-16T19:59:49.307 回答
41

表现

今天 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 对于大物体来说是慢的,对于小物体来说是中慢的

在此处输入图像描述

细节

进行了性能测试

  • 小对象 - 有 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 上小物体的结果

在此处输入图像描述

于 2020-03-06T17:36:13.543 回答
33

由于 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页面上找到更多关于使用的信息

于 2016-08-27T09:06:28.797 回答
32
for(key in p) {
  alert( p[key] );
}

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

于 2009-03-26T06:04:10.053 回答
21

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

for (var key in p) {
    console.log(key + ' => ' + p[key]);
    // key is key
    // value is p[key]
}
于 2011-08-18T20:50:22.940 回答
20

通过带有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
于 2012-12-09T05:05:51.860 回答
18

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

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

你不能仅仅因为它for...of不是Object迭代器,并且orfor...index是丑陋/低效的。 我很高兴大多数人都避免(有或没有检查),因为这也有点混乱,所以除了我上面的回答之外,我在这里说.......forEach()Object.keys()
for...in.hasOwnProperty()


你可以让普通的对象关联迭代!行为就像Maps 直接使用在 Chrome 和 FF 中工作的精美for...of
DEMO(我假设仅 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()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))

没有理由不这样做。

欢迎来到未来。

于 2016-06-28T09:42:22.837 回答
17

您还可以使用 Object.keys() 并遍历对象键,如下所示:

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

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

于 2019-08-13T07:14:45.193 回答
16

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>

于 2012-02-21T11:22:41.743 回答
16

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

Object.entries(myObject).map(([key, value]) => console.log(key, value))
于 2021-08-28T12:51:12.607 回答
15

使用for-ofObject.keys()

像:

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

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

于 2019-10-30T21:05:02.000 回答
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);
});

于 2015-06-22T09:52:04.423 回答
12

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

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

于 2018-09-11T05:55:01.460 回答
11

只有没有依赖关系的 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
}
于 2015-04-21T12:02:33.783 回答
10

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

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

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

于 2017-11-16T20:04:39.557 回答
10

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

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


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

于 2017-12-20T04:42:57.763 回答
9

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

于 2020-01-04T11:13:47.733 回答
7

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

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

于 2016-06-18T02:11:52.193 回答
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 发生冲突,您可以使用您的唯一名称命名它。

于 2016-11-22T20:46:31.383 回答
6

在可枚举的 JavaScript 对象上循环的一种好方法是 usingObject.keysObject.entrieswith usingmap函数,这对于 ReactJS 来说可能很棒而且很常见。如下所示:

// assume items:

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

用于循环并显示一些 UI,ReactJS如下所示:

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

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

于 2020-02-22T20:38:36.533 回答
5

我会这样做,而不是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");
}
于 2015-07-09T08:22:46.417 回答
5

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

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

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

这将给出与使用 for...in es6 循环相同的结果。

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

但是了解您现在使用 es6 的能力很重要!

于 2016-09-20T09:04:34.500 回答
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]);
        }
    }
}

于 2018-06-26T14:34:43.323 回答
5

从 ES06 开始,您可以将对象的值作为数组获取

let arrValues = Object.values( yourObject) ;

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

MDN 文档 Object.values()

和钥匙(在这里我已经回答了)

let arrKeys   = Object.keys(yourObject);
于 2018-07-09T16:15:57.683 回答
4

如果您还想迭代不可枚举的属性,您可以使用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/>');
});

于 2015-09-12T16:31:40.660 回答
4

如果有人需要使用条件遍历arrayObjects

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

于 2016-07-22T03:48:23.303 回答
4

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

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

让我们有book对象。

let book = {
  title: "Amazing book",
  author: "Me",
  pages: 3
}

book[Symbol.iterator] = function(){

  let properties = Object.keys(this); // returns an array with property 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生成器的强大功能,那么您当然可以使上面的代码更短。

book[Symbol.iterator] = function *(){

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

}

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

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

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

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

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

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

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

于 2016-09-01T20:15:42.470 回答
4
Object.entries(myObject).map(([key, value]) => console.log(key, value))

你可以这样试试。myObject会是{name: "", phone: ""}某某,这会产生key和value。所以这里的关键是namephone价值就像dog123123

例子{name: "dog"}

这里键是name,值是dog

于 2022-02-03T15:10:02.263 回答
3

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

于 2018-10-24T19:51:03.820 回答
1

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

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

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

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

于 2017-10-10T18:57:33.187 回答
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>

于 2019-02-07T05:28:47.820 回答
0

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

于 2017-11-13T16:05:12.827 回答
0

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

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

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

于 2018-02-07T11:22:18.420 回答
-1
  • 单级缩进
  • 单组括号
  • 最高的浏览器兼容性
  • 拥有自己的财产安全

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

于 2018-02-26T02:42:25.670 回答
-1

如果您的应用程序是在创建字符串,一个很好的组合是 Object.keys、implode 和 .map 数组方法。例如,如果我们有一个像

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 。

于 2019-06-08T18:26:18.083 回答
-3

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

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


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

希望这可以帮助某人。

于 2016-04-14T11:27:20.940 回答
-6

因为询问者的 ['最终目标是遍历一些键值对'] 并且最后不寻找循环。

var p ={"p1":"value1","p2":"value2","p3":"value3"};
if('p1' in p){
  var val=p['p1'];
  ...
}
于 2014-06-08T05:55:06.610 回答