我有一个如下的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
。
从ES06开始,您可以使用
let arrValues = Object.values( yourObject) ;
它返回对象值的数组,并且不从原型中提取值!
和钥匙(在这里我已经回答了)
let arrKeys = Object.keys(yourObject);
考虑到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。
如果有人需要遍历带有条件的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");
}
}
}
使用for-of
开Object.keys()
喜欢:
let object = {
"key1": "value1"
"key2": "value2"
"key3": "value3"
};
for (var key of Object.keys(p)) {
console.log(key + " : " + object[key])
}
在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现在所具有的功能很重要!
使用纯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
在成为新标准之前,仍然可以使用旧方法,但是流行的库中还有其他选择,甚至对于那些不使用这些库的人来说,甚至还有轻量级的选择。
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]);
}
}
}
仅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
}
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>
这是另一种遍历对象的方法。
var p = {
"p1": "value1",
"p2": "value2",
"p3": "value3"
};
Object.keys(p).forEach(key => { console.log(key, 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
for(key in p) {
alert( p[key] );
}
注意:您可以在数组上执行此操作,但是也将在length
和其他属性上进行迭代。
您可以像这样遍历它:
for (var key in p) {
alert(p[key]);
}
请注意,它key
不会采用该属性的值,而只是一个索引值。
您可以使用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])
}
请注意,使用of for-of
代替for-in
,如果不使用它将在命名属性上返回未定义,并Object.keys()
确保仅使用对象自身的属性,而不使用整个原型链属性
使用新Object.entries()
方法:
Note: This method is not supported natively by Internet Explorer. You may consider using a Polyfill for older browsers.
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
环但忽略原型链。仅迭代对象自身的可枚举属性。
在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表上看到的浏览器支持
UPD:
此问题上所有最受欢迎案例的性能比较perfjs.info
:
您必须使用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
}
在最新的ES脚本中,您可以执行以下操作: