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

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

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


当前回答

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

由于纯JS对象不能立即迭代,因此我们无法使用。。用于迭代其内容的循环。但没有人能阻止我们使其可迭代。

让我们有书的对象。

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可迭代,您可以对所有对象应用这样的行为。

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.getOwnPropertyNames(obj)

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

我有时会用它来快速测试具有简单输入和输出的对象上的所有函数。

在Object.keys()上使用for

喜欢:

let对象={“key1”:“value1”,“key2”:“value2”,“key3”:“value3”};for(let key of Object.keys(对象)){console.log(key+“:”+对象[key])}

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

注意:可以对数组执行此操作,但也要对长度和其他财产进行迭代。

有趣的是,这些答案中的人都提到了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))

这没有理由不起作用。

欢迎来到未来。

Object.entries(myObject).map(([key, value]) => console.log(key, value))

你可以这样试试。myObject将是{name:“”,phone:“”}等等,这将生成密钥和值。所以这里的关键是名字,电话和价值就像狗,123123。

示例{name:“dog”}

这里的键是名字,值是狗。