如何迭代JavaScript对象?

时间:2013-01-17 12:36:15

标签: javascript loops object iteration javascript-objects

我在JavaScript中有一个对象:

{
    abc: '...',
    bca: '...',
    zzz: '...',
    xxx: '...',
    ccc: '...',
    // ...
}

我想使用for循环来获取其属性。我想在部分中迭代它(不是一次所有对象属性)。

使用简单数组我可以使用标准for循环:

for (i = 0; i < 100; i++) { ... } // first part
for (i = 100; i < 300; i++) { ... } // second
for (i = 300; i < arr.length; i++) { ... } // last

但如何用物体做呢?

19 个答案:

答案 0 :(得分:641)

对于大多数对象,请使用for .. in

for (var key in yourobject) {
  console.log(key, yourobject[key]);
}

使用ES6,如果您同时需要键和值,请执行

for (let [key, value] of Object.entries(yourobject)) {
    console.log(key, value);
}

要避免记录继承的属性,请查看hasOwnProperty

for (var key in yourobject) {
   if (yourobject.hasOwnProperty(key)) {
      console.log(key, yourobject[key]);
   }
}

如果您使用的是一个简单的对象(例如您使用hasOwnProperty创建的对象),则在迭代键时无需检查{} < / p>

This MDN documentation更一般地解释了如何处理对象及其属性。

如果你想“以块为单位”,最好是提取数组中的键。由于订单无法保证,这是正确的方法。在现代浏览器中,您可以使用

var keys = Object.keys(yourobject);

为了更兼容,你最好这样做:

 var keys = [];
 for (var key in yourobject) {      
     if (yourobject.hasOwnProperty(key)) keys.push(key);
 }

然后,您可以按索引迭代您的属性:yourobject[keys[i]]

for (var i=300; i<keys.length && i<600; i++) { 
   console.log(keys[i], yourobject[keys[i]]);
}

答案 1 :(得分:49)

这是现代浏览器的另一种迭代解决方案:

Object.keys(obj).filter(function(k, i) {
    return i >= 100 && i < 300;
}).forEach(function(k) {
    console.log(obj[k]);
});

甚至更短:

Object.keys(obj).forEach(function(k, i) {
    if (i >= 100 && i < 300) {
        console.log(obj[k]);
    }
});

但是,您必须考虑JavaScript对象中的属性未排序,即没有顺序。

答案 2 :(得分:13)

使用新的ES6 / ES2015功能,您不必再使用对象来迭代哈希。您可以使用Map。 Javascript Maps将密钥保持在插入顺序中,这意味着您可以迭代它们而无需检查hasOwnProperty,这总是真的很糟糕。

迭代地图:

var myMap = new Map();
myMap.set(0, "zero");
myMap.set(1, "one");
for (var [key, value] of myMap) {
  console.log(key + " = " + value);
}
// Will show 2 logs; first with "0 = zero" and second with "1 = one"

for (var key of myMap.keys()) {
  console.log(key);
}
// Will show 2 logs; first with "0" and second with "1"

for (var value of myMap.values()) {
  console.log(value);
}
// Will show 2 logs; first with "zero" and second with "one"

for (var [key, value] of myMap.entries()) {
  console.log(key + " = " + value);
}
// Will show 2 logs; first with "0 = zero" and second with "1 = one"

或使用forEach:

myMap.forEach(function(value, key) {
  console.log(key + " = " + value);
}, myMap)
// Will show 2 logs; first with "0 = zero" and second with "1 = one"

答案 3 :(得分:13)

使用Object.entries你会做这样的事情。

 // array like object with random key ordering
 const anObj = { 100: 'a', 2: 'b', 7: 'c' };
 console.log(Object.entries(anObj)); // [ ['2', 'b'],['7', 'c'],['100', 'a'] ]

Object.entries()方法返回给定对象自身的可枚举属性[key,value]

的数组

因此,您可以遍历Object并为每个对象设置keyvalue,并获得类似的内容。

const anObj = { 100: 'a', 2: 'b', 7: 'c' };
Object.entries(anObj).map(obj => {
   const key   = obj[0];
   const value = obj[1];

   // do whatever you want with those values.
});

或者像这样

// Or, using array extras
Object.entries(obj).forEach(([key, value]) => {
  console.log(`${key} ${value}`); // "a 5", "b 7", "c 9"
});

有关参考,请查看Object Entries

的MDN文档

答案 4 :(得分:7)

唯一可靠的方法是将对象数据保存到2个数组,一个键和一个用于数据:

var keys = [];
var data = [];
for (var key in obj) {
    if (obj.hasOwnProperty(key)) {
        keys.push(key);
        data.push(obj[key]); // Not necessary, but cleaner, in my opinion. See the example below.
    }
}

然后,您可以像往常一样遍历数组:

for(var i = 0; i < 100; i++){
    console.log(keys[i], data[i]);
    //or
    console.log(keys[i], obj[keys[i]]); // harder to read, I think.
}
for(var i = 100; i < 300; i++){
    console.log(keys[i], data[i]);
}

我没有使用Object.keys(obj),因为那是IE 9 +。

答案 5 :(得分:4)

如果要在迭代时使用键和值,则可以将for...of循环与Object.entries一起使用。

const myObj = {a: 1, b: 2}

for (let [key, value] of Object.entries(myObj)) {
    console.log(`key=${key} value=${value}`)
}

// output: 
// key=a value=1
// key=b value=2

答案 6 :(得分:2)

- &gt;如果我们使用和查找数组的键迭代JavaScript对象   对象

<wls:weblogic-web-app
        xmlns:wls="http://xmlns.oracle.com/weblogic/weblogic-web-app"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://xmlns.oracle.com/weblogic/weblogic-web-app
        http://xmlns.oracle.com/weblogic/weblogic-web-app/1.4/weblogic-web-app.xsd">
    <wls:context-root>/reportbuilder</wls:context-root>
    <wls:container-descriptor>
        <wls:prefer-application-packages>
            <wls:package-name>org.slf4j.*</wls:package-name>
            <wls:package-name>org.springframework.*</wls:package-name>
            <wls:package-name>org.joda.time.*</wls:package-name>
        </wls:prefer-application-packages>
    </wls:container-descriptor>
</wls:weblogic-web-app>

答案 7 :(得分:1)

您可以尝试使用lodash- A modern JavaScript utility library delivering modularity, performance & extras js来快速对象迭代: -

var  users  =   {
    'fred':     { 
        'user':   'fred',
            'age':  40 
    },
    'pebbles':  { 
        'user':   'pebbles',
         'age':  1 
    }
}; 
_.mapValues(users,  function(o)  { 
    return  o.age; 
});
// => { 'fred': 40, 'pebbles': 1 } (iteration order is not guaranteed)
// The `_.property` iteratee shorthand.
console.log(_.mapValues(users,  'age')); // returns age property & value 
console.log(_.mapValues(users,  'user')); // returns user property & value 
console.log(_.mapValues(users)); // returns all objects 
// => { 'fred': 40, 'pebbles': 1 } (iteration order is not guaranteed)
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash-compat/3.10.2/lodash.js"></script>

答案 8 :(得分:1)

如果您有一个简单的对象,则可以使用以下代码对其进行迭代:

let myObj = {
  abc: '...',
  bca: '...',
  zzz: '...',
  xxx: '...',
  ccc: '...',
  // ...
};

let objKeys = Object.keys(myObj);

//Now we can use objKeys to iterate over myObj

for (item of objKeys) {
  //this will print out the keys
  console.log('key:', item);
  
  //this will print out the values 
  console.log('value:', myObj[item]);
}

如果您有嵌套的对象,则可以使用以下代码对其进行迭代:

let b = {
  one: {
    a: 1,
    b: 2,
    c: 3
  },
  two: {
    a: 4,
    b: 5,
    c: 6
  },
  three: {
    a: 7,
    b: 8,
    c: 9
  }
};

let myKeys = Object.keys(b);

for (item of myKeys) {
  //print the key
  console.log('Key', item)
  
  //print the value (which will be another object)
  console.log('Value', b[item])
  
  //print the nested value
  console.log('Nested value', b[item]['a'])
}

如果您有对象数组,则可以使用以下代码对其进行迭代:

let c = [
{
  a: 1,
  b: 2
},
{
  a: 3,
  b: 4
}
];

for(item of c){
//print the whole object individually 
console.log('object', item);

//print the value inside the object
console.log('value', item['a']);
}

答案 9 :(得分:1)

对于对象迭代,我们通常使用for..in循环。该结构将遍历所有可枚举属性,包括通过原型继承继承的属性。例如:

let obj = {
  prop1: '1',
  prop2: '2'
}

for(let el in obj) {
  console.log(el);
  console.log(obj[el]);
}

但是,for..in将遍历所有可枚举的元素,这将使我们无法将迭代拆分为多个块。为此,我们可以使用内置的Object.keys()函数来检索数组中对象的所有键。然后,我们可以将迭代分为多个for循环,并使用keys数组访问属性。例如:

let obj = {
  prop1: '1',
  prop2: '2',
  prop3: '3',
  prop4: '4',
};

const keys = Object.keys(obj);
console.log(keys);


for (let i = 0; i < 2; i++) {
  console.log(obj[keys[i]]);
}


for (let i = 2; i < 4; i++) {
  console.log(obj[keys[i]]);
}

答案 10 :(得分:1)

真的是PITA,这不是标准Javascript的一部分。

/**
 * Iterates the keys and values of an object.  Object.keys is used to extract the keys.
 * @param object The object to iterate
 * @param fn (value,key)=>{}
 */
function objectForEach(object, fn) {
    Object.keys(object).forEach(key => {
        fn(object[key],key, object)
    })
}

注意:我将回调参数切换为(value,key)并添加了第三个对象,以使API与其他API保持一致。

像这样使用

const o = {a:1, b:true};
objectForEach(o, (value, key, obj)=>{
    // do something
});

答案 11 :(得分:1)

我终于提出了一个方便的实用程序函数,它具有统一的接口来迭代对象,字符串,数组,TypedArrays,Maps,Sets,(任何Iterables)。

public void launchWebsite(String url) {
    Intent openURL = new Intent(android.content.Intent.ACTION_VIEW);
    openURL.setData(Uri.parse("https://www." + url + ".com"));
    startActivity(openURL);

}

https://github.com/alrik/iterate-javascript

答案 12 :(得分:1)

如果您想立即迭代整个对象,可以使用for in循环:

for (var i in obj) {
  ...
}

但是如果你想将对象分成几部分实际上你不能。无法保证对象中的属性具有任何指定的顺序。因此,我可以想到两个解决方案。

首先是“删除”已读取的属性:

var i = 0;
for (var key in obj) {
    console.log(obj[key]);
    delete obj[key];
    if ( ++i > 300) break;
}

我能想到的另一个解决方案是使用数组而不是对象:

var obj = [['key1', 'value1'], ['key2', 'value2']];

然后,标准for循环将起作用。

答案 13 :(得分:0)

var Dictionary = {
  If: {
    you: {
      can: '',
      make: ''
    },
    sense: ''
  },
  of: {
    the: {
      sentence: {
        it: '',
        worked: ''
      }
    }
  }
};

function Iterate(obj) {
  for (prop in obj) {
    if (obj.hasOwnProperty(prop) && isNaN(prop)) {
      console.log(prop + ': ' + obj[prop]);
      Iterate(obj[prop]);
    }
  }
}
Iterate(Dictionary);

答案 14 :(得分:0)

是的。您可以使用for循环遍历对象。这是一个例子

[HttpPost]
public IActionResult SearchPerson(IFormCollection formCollection)
{
   string txtState = formCollection["States"];

注意::上述示例仅在IE9 +中有效。请参阅Objec.keys浏览器支持here

答案 15 :(得分:0)

使用ES6时,您同时需要键和值,请执行这些方法。

for (let [key, value] of Object.entries(your_object)) {
     console.log(key, value);
}

答案 16 :(得分:0)

const o = {
  name: "Max",
  location: "London"
};

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

Try online

答案 17 :(得分:0)

这是一个手工制作的解决方案:

Main

然后您可以循环播放任何对象:

"${workspaceFolder:Secondary:includePath}"

答案 18 :(得分:0)

<script type="text/javascript">
// method 1
var images = {};
images['name'] = {};
images['family'] = {};
images[1] = {};
images['name'][5] = "Mehdi";
images['family'][8] = "Mohammadpour";
images['family']['ok'] = 123456;
images[1][22] = 2602;
images[1][22] = 2602;
images[1][22] = 2602;
images[1][22] = 2602;
images[1][23] = 2602;

for (const [key1, value1] of Object.entries(images)){
    for (const [key2, value2] of Object.entries(value1)){
        console.log(`${key1} => ${key2}: ${value2}`);
    }
}


console.log("=============================");

// method 2
var arr = [];
for(var x = 0; x < 5; x++){
     arr[x] = [];    
     for(var y = 0; y < 5; y++){ 
         arr[x][y] = x*y;    
     }    
 }

for(var i = 0; i < arr.length; i++) {
    var cube = arr[i];
    for(var j = 0; j < cube.length; j++) {
        console.log("cube[" + i + "][" + j + "] = " + cube[j]);
    }
}

</script>