我有一个如下所示的 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]);
}
}
For-of 与 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
,如果不使用它将在命名属性上返回 undefined,并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()
(或它的 alias _.each()
)对于循环遍历对象和数组很有用,但是(!)具有length
属性的对象被视为数组,并且为了避免这种行为,建议使用_.forIn()
和_.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,规格] -提供一个对象的名称的数组的函数自己的,枚举的性质,其名称是字符串。Object.values
[ MDN,规格] -甲函数提供所述的阵列值的对象的的自己的,枚举的属性。Object.entries
[ MDN,规格] -提供所述名称的数组的函数和一个对象的值自身,可枚举属性(阵列中的每个条目是[name, value]
阵列)。Object.getOwnPropertyNames
[ MDN , spec ] — 一个函数,提供名称为字符串的对象自身属性(甚至不可枚举的)的名称数组。Object.getOwnPropertySymbols
[ MDN , spec ] — 一个函数,提供名称为 Symbols的对象自身属性(甚至不可枚举的)的名称数组。Reflect.ownKeys
[ MDN , spec ] — 一个函数,提供对象自身属性(甚至不可枚举的)的名称数组,无论这些名称是字符串还是符号。Object.getPrototypeOf
[ MDN , spec ] 并在原型链中的每个对象上使用Object.getOwnPropertyNames
, Object.getOwnPropertySymbols
, 或Reflect.ownKeys
(此答案底部的示例)。随着所有这些硬盘中for-in
,你会使用某种类型的阵列上的循环结构(中for
,for-of
,forEach
,等)。
例子:
for-in
:
Object.keys
(使用for-of
循环,但您可以使用任何循环构造):
Object.values
:
Object.entries
:
Object.getOwnPropertyNames
:
Object.getOwnPropertySymbols
:
Reflect.ownKeys
:
所有属性,包括继承的不可枚举的: