在JavaScript中,严格来说所有的数据类型鼻祖都是Object,所以我们来看看以下这个例子:

1
2
3
4
5
6
7
8
9
10
var arr = ["a", "b", "c"];
undefined
>>> for(var i=0; i<arr.length; i++){ console.log(i); }
0
1
2
>>> for(var i in arr){ console.log(i); }
0
1
2

以上例子定义了一个包含3个元素的数组arr,然后分别使用for和for-in来遍历它的元素,结果都没问题。但如果我给arr添加一个原型方法,结果就不一样了。

1
2
3
4
Array.prototype.len = function(){ return this.length; };
function()
>>> arr.len()
3

给数组原型添加了一个自定义len方法,然后再使用for和for-in来遍历它

1
2
3
4
5
6
7
8
9
for(var i=0; i<arr.length; i++){ console.log(i); } 
0
1
2
>>> for(var i in arr){ console.log(i); }
0
1
2
len

for循环没问题,但for-in却把我们自定义的len方法也给遍历出来了,可是arr.length还是等于3。这说明for-in会把Array当做一个Object来遍历所有成员包含Array的元素,len做为arr的成员自然也就被遍历出来。

然后有人就说,那我不给数组添加原型方法,那用for-in就没问题,可是你又敢保证有人不这么干吗?

1
2
3
4
var arr = [];
undefined
>>> arr.id = Date.now()
1390099868440

包括String类型同样使用for-in要注意,看下面例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
var str = "qttc";
undefined
>>> String.prototype.lastChar = function(){ return this.charAt(this.length-1) }
function()
>>> str.lastChar()
"c"
>>> str.length
4
>>> for(var i=0; i<str.length; i++){ console.log(i); }
0
1
2
3
>>> for(var i in str){ console.log(i); }
0
1
2
3
lastChar

这个例子很好的说明了for与for-in的区别,所以反过来你想要知道某个String或者Array或者任意类型的对象被添加了什么方法都可以使用for-in获得,for-in是最彻底的。