# forin 和 forof 的区别
# 1. 遍历数组通常用 for 循环
ES5 的话也可以使用 forEach, ES5 具有遍历数组功能的还有 map, filter, some, every, reduce, reduceRight 等,只不过他们的返回结果不太一样,但使用 forEach 遍历数组的话,使用 break 不能中断循环,使用 return 也不能返回到外层函数。
Array.prototype.method = function() {
console.log(this.length);
};
var myArray = [1, 2, 3, 4, 5];
myArray.name = "数组";
for (var index in myArray) {
console.log(myArray[index]);
}
# 2. for in 遍历数组的毛病
- index 索引为字符串型数字,不能直接进行几何运算
- 遍历顺序有可能不是按照实际数组的内部顺序
- 使用
for in
会遍历数组所有的可枚举属性,包括原型。例如上例的原型方法 method 和 name 属性 所以for in
更适合遍历对象,不要使用for in
遍历数组 可以用for of
遍历数组
- 使用
for in 遍历的是数组的索引(即键名),而 for of 遍历的是数组的元素值 for of 遍历的只是组内的元素,而不包括数组的原型属性 method 和索引 name
Array.prototype.method = function() {
console.log(this.length);
};
var myArray = [1, 2, 3, 4, 5];
myArray.name = "数组";
for (var value of myArray) {
console.log(value);
}
# 遍历对象
遍历对象 通常用for in
来遍历对象的键名
Object.prototype.method = function() {
console.log(this);
};
var myObject = {
a: 1,
b: 2,
c: 3,
};
for (var key in myObject) {
console.log(key);
}
for in
可以遍历到 myObject 的原型方法 method,如果不想遍历原型方法和属性,可以在项目内部加判断,hasOwnPropery
方法可以判断某属性是否是该对象的实例属性
for (var key in myObject) {
if (myObject.hasOwnProperty(key)) {
console.log(key);
}
}
同样可以通过 es5 的Object.keys(myObject)
获取对象的实例属性组成的数组,不包括原型方法和属性
Object.prototype.method = function() {
console.log(this);
};
var myObject = {
a: 1,
b: 2,
c: 3,
};
for (var key of Object.keys(myObject)) {
console.log(key + ": " + myObject[key]);
}
# 总结
for...of
适用遍历数/数组对象/字符串/map/set 等拥有迭代器对象的集合。但不能遍历对象,因为没有迭代器的对象。与 forEach()不同的是,它可以正确响应 break、continue 和 return 语句。for...of
循环不支持普通对象,但如果你想迭代一个对象属性,你可以用for-in
循环,或内建 Object.keys()方法
for (var key of Object.keys(someObjec)) {
console.log(key + ": " + someObjec[key]);
}
- 遍历 map 对象时使用解构
for (var [key, value] of phoneBookeMap) {
console.log(key + "'s phone number is: " + value);
}
- 向任意对象添加
[Symbol.itertor]
方法,就可以使用for..of
循环了- 所有拥有
Symbol.iterator
的对象被称为可迭代的。
- 所有拥有
jQuery.prototype[Symbol.iterator] = Array.prototype[Symbol.iterator];
- for..of 步骤
- a. 首先调用集合
Symbol.iterator
方法,从而返回一个新的迭代对象 - b. 迭代器对象可以是任意具有
.next()
方法的对象,forof 循环将重复调用这个方法,每次循环调用一次。
var zeroesForeverIterator = { [Symbol.iterator]: function() { return this; }, next: function() { return { done: false, value: 0, }; }, };
- a. 首先调用集合