首页 文章

如何循环或枚举JavaScript对象?

提问于
浏览
2305

我有一个像以下JavaScript对象:

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

现在我想遍历所有 p 元素( p1p2p3 ...)并获取它们的键和值 . 我怎样才能做到这一点?

如有必要,我可以修改JavaScript对象 . 我的最终目标是遍历一些键值对,如果可能的话,我想避免使用 eval .

30 回答

  • 4
    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]);
            }
        }
    }
    
  • 48

    只有没有依赖关系的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
    }
    
  • 7

    考虑到ES6,我想添加自己的糖,并提供一种迭代对象属性的方法 .

    由于普通JS对象不是iterable,因此我们无法使用 for..of 循环来迭代其内容 . 但没有人可以阻止我们 to make it iterable .

    我们有 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 generators的强大功能,那么您肯定可以使上面的代码更短 .

    book[Symbol.iterator] = function *(){
    
      let properties = Object.keys(this);
      for (let p of properties){
        yield this[p];
      }
    
    }
    

    当然,您可以在 prototype 级别上使 Object 可迭代地对所有对象应用此类行为 .

    Object.prototype[Symbol.iterator] = function() {...}
    

    此外,符合可迭代协议的对象可以与新的ES2015功能spread运算符一起使用,因此我们可以将对象属性值作为数组读取 .

    let pValues = [...book];
    console.log(pValues);
    -------------------------
    ["Amazing book", "Me", 3]
    

    或者您可以使用destructuring赋值:

    let [title, , pages] = book; // notice that we can just skip unnecessary values
    console.log(title);
    console.log(pages);
    ------------------
    Amazing book
    3
    

    您可以查看我上面提供的所有代码JSFiddle .

  • 1

    如果你想迭代 non-enumerable properties ,你可以使用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] + '
    '); });
  • 21

    实现.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
    
  • 3

    在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的功能非常重要!

  • 3

    在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)
    );
    

    Object.keys()Object.entries() 都以与 for...in 循环相同的顺序迭代属性,但忽略原型链 . 只迭代对象自己的可枚举属性 .

  • 37

    这是迭代对象的另一种方法 .

    var p = {
    "p1": "value1",
    "p2": "value2",
    "p3": "value3"
    };
    
    
    Object.keys(p).forEach(key => { console.log(key, p[key]) })
    
  • 726

    前言:

    • 对象属性可以是自己的(属性在对象本身上)或继承(不在对象本身上,在其中一个原型上) .

    • 对象属性可以是可枚举的,也可以是不可枚举的 . 不可枚举的属性被排除在许多属性枚举/数组之外 .

    • 属性名称可以是字符串或符号 . 名称为Symbols的属性不在许多属性枚举/数组中 .

    在2018年,您循环访问对象属性的选项是:

    • for-in [MDNspec] - 循环结构,循环访问对象的可枚举属性的名称,包括继承的属性,其名称为字符串

    • Object.keys [MDNspec] - 一个函数,提供对象自身的名称数组,其名称为字符串 .

    • Object.values [MDNspec] - 提供对象自身可枚举属性值的数组的函数 .

    • Object.entries [MDNspec] - 一个函数,提供对象自身可枚举属性的名称和值的数组 .

    • Object.getOwnPropertyNames [MDNspec] - 一个函数,提供一个对象自己的属性名称数组(甚至是不可枚举的属性),其名称为字符串 .

    • Object.getOwnPropertySymbols [MDNspec] - 一个函数,提供一个对象自己的属性名称数组(甚至是不可枚举的属性),其名称为Symbols .

    • Reflect.ownKeys [MDNspec] - 提供对象自身属性名称数组的函数(即使是不可枚举的属性),无论这些名称是字符串还是符号 .

    • 如果你想要对象的属性 all ,包括不可枚举的继承属性,你需要使用一个循环和 Object.getPrototypeOf [MDNspec]并在原型链中的每个对象上使用 Object.getOwnPropertyNamesObject.getOwnPropertySymbolsReflect.ownKeys (底部的例子)这个答案) .

    除了 for-in 之外的所有这些,你将在数组上使用某种循环结构( forfor-offorEach 等) .

    例子:

    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}`);
    }
    

    All properties ,包括继承的非可枚举的:

    // 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;
    }
    
  • 235

    我会这样做而不是在每个 for ... in 循环中检查 obj.hasOwnerProperty .

    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");
    }
    
  • 15

    如果有人需要循环 arrayObjects with condition

    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");
          }
       }
    }
    
  • 2

    你必须使用 for-in loop

    但是在使用这种循环时要非常小心,因为这将是 loop all the properties along the prototype chain .

    因此,在使用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
    }
    
  • 3

    在查看了这里的所有答案之后,我自己的用法不需要hasOwnProperty,因为我的json对象是干净的;添加任何额外的JavaScript处理真的没有意义 . 这就是我正在使用的:

    for (var key in p) {
        console.log(key + ' => ' + p[key]);
        // key is key
        // value is p[key]
    }
    
  • 5

    您可以向所有对象添加一个简单的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”-method的人:

    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发生冲突,可以使用您的唯一名称命名 .

  • 3

    使用纯JavaScript时,循环可能非常有趣 . 似乎只有ECMA6(New 2015 JavaScript规范)才能控制循环 . 不幸的是,当我写这篇文章时,浏览器和流行的集成开发环境(IDE)仍在努力完全支持新的花里胡哨 .

    这里是一个JavaScript对象循环在ECMA6之前的样子:

    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仅为Arrays添加了 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

    在这成为新标准之前,仍然可以使用旧方法,但在流行的库中也有替代方案,甚至对于那些没有使用任何这些库的人来说也是如此 .

  • 0

    如果我们不提及循环对象的替代方法,那么问题就不会完整 .

    如今,许多众所周知的JavaScript库提供了自己的迭代集合的方法,即在数组,对象和类似数组的对象上 . 这些方法使用方便,并且与任何浏览器完全兼容 .

    • 如果使用 jQuery ,则可以使用jQuery.each()方法 . 它可用于无缝迭代对象和数组:
    $.each(obj, function(key, value) {
        console.log(key, value);
    });
    
    • Underscore.js 中你可以找到方法_.each(),它迭代一个元素列表,依次产生一个提供的函数(注意iteratee函数中参数的顺序!):
    _.each(obj, function(value, key) {
        console.log(key, value);
    });
    
    • Lo-Dash 提供了几种迭代对象属性的方法 . Basic _.forEach()(或它的别名 _.each() )对于循环遍历对象和数组很有用,但是具有 length 属性的(!)对象被视为数组,为避免这种行为,建议使用_.forIn()_.forOwn()方法(这些方法也有 value )争论第一):
    _.forIn(obj, function(value, key) {
        console.log(key, value);
    });
    

    _.forIn() 迭代对象的自有和继承的可枚举属性,而 _.forOwn() 仅迭代对象的自有属性(基本上检查 hasOwnProperty 函数) . 对于简单对象和对象文字,这些方法中的任何一种都可以正常工作 .

    通常,所有描述的方法与任何提供的对象具有相同的行为 . 除了使用原生 for..in 循环通常会比任何抽象更快,例如 jQuery.each() ,这些方法更容易使用,需要更少的编码并提供更好的错误处理 .

  • 2
    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>
    
  • 17

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

    Here is the snippet:

    var p = {
        "p1": "value1",
        "p2": "value2",
        "p3": "value3"
    };
    
    for (var key in p) {
        if (p.hasOwnProperty(key)) {
            console.log(key + " -> " + p[key]);
        }
    }
    
  • 24

    有趣的是,这些答案中的人都触及了 Object.keys()for...of 但从未合并过:

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

    你不能仅仅因为它不是一个迭代器,而是因为它不是一个迭代器,而对于...索引或.forEach()来说,Object.keys()是丑陋/低效的 . 我很高兴大多数人都避免......在(有或没有检查.hasOwnProperty())因为这也有点乱,所以除了上面的回答,我在这里说...


    You can make ordinary object associations iterate! Behaving just like Maps with direct use of the fancy for...of
    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:'!'});
    

    For those who don't like to shim, or mess with prototype in general, feel free to make the function on window instead, calling it something like 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))
    

    There's no reason why that wouldn't work.

    欢迎来到未来 .

  • 2

    Object.keys(obj):Array检索所有可枚举的(非继承)属性的所有字符串值键 .

    因此,它通过使用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中,我有以下结果

    • Object.keys方法花费了40.21101451665163毫秒 .

    • for ... in / hasOwnProperty方法花了98.26163508463651毫秒 .

    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);
    });
    
  • 5

    Object.keys() 方法返回给定对象自己的可枚举属性的数组 . 了解更多信息here

    var p = {
        "p1": "value1",
        "p2": "value2",
        "p3": "value3"
    };
    
    Object.keys(p).map((key)=> console.log(key + "->" + p[key]))
    
  • 8

    由于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页面上找到迭代器和生成器的所有信息 .

    希望它帮助了某人 .

    EDIT:

    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页面上找到有关使用的更多信息

  • 14

    在最新的ES脚本中,您可以执行以下操作:

    Object.entries(p);
    
  • 8

    在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's compat table上看到的浏览器支持

    对于旧浏览器,您有simplefull polyfill

    UPD:

    perfjs.info 中此问题中所有最常见案例的性能比较:

    object literal iteration

  • 9

    通过 prototypeforEach() ,它应该跳过 prototype chain 属性:

    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
    
  • 3708

    使用Angular时遇到了类似的问题,这是我找到的解决方案 .

    Step 1. 获取所有对象键 . 使用Object.keys . 此方法返回给定对象自己的可枚举属性的数组 .

    Step 2. 创建一个空数组 . 这是所有属性都将存在的地方,因为你的新ngFor循环将指向这个数组,我们必须全部捕获它们 . Step 3. 迭代抛出所有键,并将每个键推入您创建的数组中 . 这是代码中的样子 .

    // 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

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

    注意:您可以在数组上执行此操作,但您也将迭代 length 和其他属性 .

  • 310

    如果你只想对属性进行迭代,请使用上面的一个答案,但是如果你想迭代包括函数在内的所有东西,那么你可能想要使用Object.getOwnPropertyNames(obj)

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

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

  • 17

    从ES06开始,您可以将对象的值作为数组获取

    let arrValues = Object.values( yourObject) ;
    

    它返回一个对象值的数组,它不从Prototype中提取值!

    MDN DOCS Object.values()

    和钥匙(已经在我面前回答)

    let arrKeys   = Object.keys(yourObject);
    
  • 12

    您可以像以下一样迭代它:

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

    请注意, key 不会采用属性的值,它只是一个索引值 .

相关问题