JavaScript中for...in循环使用问题
问题
使用for...in去遍历一个数组,同时将值添加到另外一个数组时,新的数组中每次都多出来一个function类型的元素。
原因及解决方案
for...in用来循环本身没有问题,但是经常被误用来遍历数组或者类似数据的对象。
for...in的本意是用来遍历对象的属性,这就会导致遍历时上升到原型链的层次,不仅会遍历自身的属性,还会遍历继承获得的属性,然而有时这是不需要的。
另外,即使确定要遍历的数组没有继承属性,在使用for...in进行遍历时,并不能保证获取的元素顺序和数组中原始顺序一致。
例如在JScript (IE <= 8)
中,遍历数组的顺序是元素加入数组的顺序
var array = [];
array[2] = 'c';
array[1] = 'b';
array[0] = 'a';
for (var p in array) {
//... p will be "2", "1" and "0" on IE
}
另外,对于继承属性,如果你扩展了Array.prototype
对象,这个扩展属性也会被遍历出来
Array.prototype.last = function () { return this[this.length-1]; };
for (var p in []) { // an empty array
// last will be enumerated
}
使用for...in遍历一个对象的属性时,如果只想遍历对象本身的属性,那么可以使用hasOwnProperty
方法进行判断
for (var prop in obj) {
if (obj.hasOwnProperty(prop)) {
// prop is not inherited
}
}
如果要遍历一个数组或者一个类似数组的对象,最好是使用一个顺序循环,例如一个普通的for/while循环,也可以使用ES6中的for...of循环。
for...of循环例子:
//循环一个数组
let iterable = [10, 20, 30];
for (let value of iterable) {
console.log(value);
}
//循环一个字符串
let iterable = "boo";
for (let value of iterable) {
console.log(value);
}
//循环一个map
let iterable = new Map([["a", 1], ["b", 2], ["c", 3]]);
for (let [key, value] of iterable) {
console.log(value);
}
//或者
for (let entry of iterable) {
console.log(entry);
}
//循环一个拥有enumerable属性的对象
for (var key of Object.keys(someObject)) {
console.log(key + ": " + someObject[key]);
}