本系列的文章都是在阅读《编写可维护的JavaScript》——Nicbolas C. Zakas 的基础上做的一些个人总结
for-in 循环
### 遍历对象
对对象使用for in
循环的时候,一般情况下,都应该使用hasOwnProperty()
方法来进行过滤:
var prop,
obj = {
a: "aaa",
b: "bbb"
};
for (prop in obj) {
if (obj.hasOwnProperty(prop) {
console.log("Property name is " + prop);
console.log("Property value is " + obj\[prop\]);
}
}
如果的确需要查询原型链,这个时候应当补充注释
var prop,
obj = {
a: "aaa",
b: "bbb"
};
for (prop in obj) { // 包含对原型链的遍历
console.log("Property name is " + prop);
console.log("Property value is " + obj\[prop\]);
}
### 不要使用for in 来遍历数组
// 不好的用法
var values = \[ 1, 2, 3, 4, 5, 6, 7\],
i;
for (i in values) {
console.log(values\[i\]);
}
不使用for in来遍历数组,是因为这样会造成一些潜在的错误,同时会有性能上面的影响。 潜在的错误:
var arr = \[ 'a', 'b', 'c'\],
i;
arr.test = 'ddd';
for ( i in arr ){
console.log(i,arr\[i\]);
}
/** 输出内容
* 0 a
* 1 b
* 2 c
* test tset
*/
可见for in循环会把用户附加在数组上的一些自定义属性输出,这很可能会导致一些潜在的错误,因为这段代码的作者的目的是需要的数组成员的数据 性能问题(摘自JavaScript秘密花园):
由于 for in 循环会枚举原型链上的所有属性,唯一过滤这些属性的方式是使用 hasOwnProperty 函数, 因此会比普通的 for 循环慢上好多倍。
做个测试:
var arr = \[\],
i,
a,
max = 100000,
timeStart,
timeEnd;
// 生成一个长度100000的数组
for (i = 0; i < max; i++) {
arr\[i\] = i;
}
/**
* for 循环
*/
timeStart = new Date().valueOf();
for (i = 0; i < max; i++) {
// 无意义的一些操作
a = arr\[i\];
}
timeEnd = new Date().valueOf();
console.log(timeEnd - timeStart);
/**
* for in 循环
*/
timeStart = new Date().valueOf();
for (i in arr) {
// 无意义的一些操作
a = arr\[i\];
}
timeEnd = new Date().valueOf();
console.log(timeEnd - timeStart);
在数组长度比较小的时候,两者差距不大 甚至有的时候for in还会快一点 但是随着数组长度越来越大,两者的差距也就越来越明显 下面是一串本机的测试数据(Mac Chrome 37.0.2062.122)
数组长度 | for | for-in |
---|---|---|
10 | 0 | 0 |
1000 | 0 | 1 |
10000 | 1 | 6 |
100000 | 2 | 46 |
1000000 | 24 | 331 |
10000000 | 207 | 4362 |
虽然在实际项目中,数组的长度不会那么长,但是能提高一点效率总是好的
原创内容,欢迎转载 😊