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

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

我如何循环遍历p的所有元素(p1、p2、p3…)并获取它们的键和值?


当前回答

有趣的是,这些答案中的人都提到了Object.keys()和for。。。但从未组合:

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

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


您可以使普通对象关联迭代!行为就像地图一样,直接使用了。。。属于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:'!'});

对于那些不喜欢填充,或者不喜欢处理原型的人,可以在窗口上创建函数,然后调用类似于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:'!'}))

or

for (let pair of getObjIterator(ordinaryObject))

这没有理由不起作用。

欢迎来到未来。

其他回答

您必须使用for in循环

但在使用这种循环时要非常小心,因为这将沿着原型链循环所有财产。

因此,在循环中使用for时,请始终使用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
}

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

下面是片段:变量p={“p1”:“值1”,“p2”:“值2”,“p3”:“值3”};for(p中的var键){if(p.hasOwnProperty(键)){console.log(键+“->”+p[key]);}}

对于具有Object.keys()选项的:

变量p={0:“值1”,“b”:“值2”,键:“value3”};for(Object.keys(p)的var键){console.log(key+“->”+p[key])}

请注意for-of而不是for-in的用法,如果不使用,它将在命名的财产上返回undefined,并且Object.keys()确保只使用对象自己的财产,而不使用整个prototype-chain财产

使用新的Object.entries()方法:

注意:Internet Explorer本机不支持此方法。您可以考虑将Polyfill用于较旧的浏览器。

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

for (const [key, value] of Object.entries(p)) {
  console.log(`${key}: ${value}`);
}

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

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

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

通过带有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