我有一个 JavaScript 对象,如下所示:
var p = {
"p1": "value1",
"p2": "value2",
"p3": "value3"
};
现在我想遍历所有p
元素(p1
, p2
, p3
...)并获取它们的键和值。我怎样才能做到这一点?
如有必要,我可以修改 JavaScript 对象。我的最终目标是遍历一些键值对,如果可能的话,我想避免使用eval
.
我有一个 JavaScript 对象,如下所示:
var p = {
"p1": "value1",
"p2": "value2",
"p3": "value3"
};
现在我想遍历所有p
元素(p1
, p2
, p3
...)并获取它们的键和值。我怎样才能做到这一点?
如有必要,我可以修改 JavaScript 对象。我的最终目标是遍历一些键值对,如果可能的话,我想避免使用eval
.
您可以使用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}`);
}
在 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
您必须使用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
}
如果我们不提到循环对象的替代方法,这个问题就不会完整。
如今,许多著名的 JavaScript 库都提供了自己的方法来迭代集合,即遍历数组、对象和类数组对象。这些方法使用方便,完全兼容任何浏览器。
如果您使用jQuery,您可以使用jQuery.each()
方法。它可用于无缝迭代对象和数组:
$.each(obj, function(key, value) {
console.log(key, value);
});
在Underscore.js中,您可以找到 method _.each()
,它遍历元素列表,将每个元素依次生成给提供的函数(注意iteratee函数中参数的顺序!):
_.each(obj, function(value, key) {
console.log(key, value);
});
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()
,这些方法更容易使用,需要更少的编码并提供更好的错误处理。
前言:
在 2018 年,您可以选择循环遍历对象的属性(列表后面有一些示例):
for-in
[ MDN , spec ] — 一种循环结构,遍历对象的可枚举属性的名称,包括继承的属性,其名称为字符串Object.keys
[ MDN , spec ] — 一个函数,提供一个对象自己的名称数组,其名称是字符串的可枚举属性。Object.values
[ MDN , spec ] — 一个函数,提供对象自身的可枚举属性的值数组。Object.entries
[ MDN , spec ] — 一个函数,提供对象自己的可枚举属性的名称和值的数组(数组中的每个条目都是一个数组)。[name, value]
Object.getOwnPropertyNames
[ MDN , spec ] — 一个函数,提供一个对象自身属性(甚至是不可枚举的属性)的名称数组,其名称是字符串。Object.getOwnPropertySymbols
[ MDN , spec ] — 一个函数,提供名称为符号的对象自身属性(甚至是不可枚举的属性)的名称数组。Reflect.ownKeys
[ MDN , spec ] — 提供对象自身属性(甚至是不可枚举属性)名称数组的函数,无论这些名称是字符串还是符号。Object.getPrototypeOf
[ MDN , spec ] 和 use Object.getOwnPropertyNames
, Object.getOwnPropertySymbols
, or Reflect.ownKeys
(本答案底部的示例)。对于除 之外的所有这些for-in
,您将在数组上使用某种循环构造(for
、for-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;
}
你可以像这样迭代它:
for (var key in p) {
alert(p[key]);
}
请注意,key
不会采用属性的值,它只是一个索引值。
在 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上的不同实现进行比较:
升级版:
此问题中所有最流行案例的性能比较perfjs.info
:
今天 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,对于大对象也很快,但在其他浏览器上速度中等)进行了性能测试
下面的片段介绍了使用的解决方案
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 上小物体的结果
由于 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(key in p) {
alert( p[key] );
}
注意:您可以对数组执行此操作,但您也将遍历 thelength
和其他属性。
在查看了这里的所有答案后,我自己的使用不需要 hasOwnProperty,因为我的 json 对象是干净的;添加任何额外的javascript处理真的没有意义。这就是我正在使用的所有内容:
for (var key in p) {
console.log(key + ' => ' + p[key]);
// key is key
// value is p[key]
}
通过带有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
有趣的是,这些答案中的人都触及了两者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()
你可以让普通的对象关联迭代!行为就像Map
s 直接使用在 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))
欢迎来到未来。
您还可以使用 Object.keys() 并遍历对象键,如下所示:
var p = {
"p1": "value1",
"p2": "value2",
"p3": "value3"
};
Object.keys(p).forEach((key)=> {
console.log(key +' -> '+ p[key]);
});
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>
单行和更具可读性的代码可以是..
Object.entries(myObject).map(([key, value]) => console.log(key, value))
使用for-of
开Object.keys()
像:
let object = {
"key1": "value1",
"key2": "value2",
"key3": "value3"
};
for (let key of Object.keys(object)) {
console.log(key + " : " + object[key])
}
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 中,我有以下结果
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);
});
在最新的 ES 脚本中,您可以执行以下操作:
let p = {foo: "bar"};
for (let [key, value] of Object.entries(p)) {
console.log(key, value);
}
只有没有依赖关系的 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
}
该Object.keys()
方法返回给定对象自己的可枚举属性的数组。在此处阅读有关它的更多信息
var p = {
"p1": "value1",
"p2": "value2",
"p3": "value3"
};
Object.keys(p).map((key)=> console.log(key + "->" + p[key]))
这是另一种遍历对象的方法。
var p = {
"p1": "value1",
"p2": "value2",
"p3": "value3"
};
Object.keys(p).forEach(key => { console.log(key, p[key]) })
在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.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}`)
})
使用纯 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
在这成为新标准之前,仍然可以使用旧方法,但在流行的库中也有替代方案,甚至对于那些不使用任何这些库的人来说,也有轻量级的替代方案。
您可以为所有对象添加一个简单的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 发生冲突,您可以使用您的唯一名称命名它。
在可枚举的 JavaScript 对象上循环的一种好方法是 usingObject.keys
或Object.entries
with 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
一次用于获取name
和price
。
我会这样做,而不是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");
}
在 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 的能力很重要!
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]);
}
}
}
从 ES06 开始,您可以将对象的值作为数组获取
let arrValues = Object.values( yourObject) ;
它返回对象值的数组,而不是从原型中提取值!!
和钥匙(在这里我已经回答了)
let arrKeys = Object.keys(yourObject);
如果您还想迭代不可枚举的属性,您可以使用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/>');
});
如果有人需要使用条件遍历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");
}
}
}
考虑到 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 。
Object.entries(myObject).map(([key, value]) => console.log(key, value))
你可以这样试试。myObject
会是{name: "", phone: ""}
某某,这会产生key和value。所以这里的关键是name
,phone
价值就像dog
,123123
。
例子{name: "dog"}
这里键是name
,值是dog
。
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);
}
我在使用 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
这是如何遍历一个 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>
对象在实现 .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
如果您只想遍历属性,请使用上述答案之一,但是如果您想遍历包括函数在内的所有内容,那么您可能需要使用Object.getOwnPropertyNames(obj)
for (let o of Object.getOwnPropertyNames(Math)) {
console.log(o);
}
我有时使用它来快速测试具有简单输入和输出的对象上的所有功能。
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);
}
如果您的应用程序是在创建字符串,一个很好的组合是 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 。
从 ES2015 开始,您可以使用 for of 循环来直接访问元素:
// before ES2015
for(var key of elements){
console.log(elements[key]);
}
// ES2015
for(let element of elements){
console.log(element);
}
希望这可以帮助某人。
因为询问者的 ['最终目标是遍历一些键值对'] 并且最后不寻找循环。
var p ={"p1":"value1","p2":"value2","p3":"value3"};
if('p1' in p){
var val=p['p1'];
...
}