一段标准的for循环代码:
var colors = ['red','green','blue'];
for(var i=0; len=colors.length; i<len; i++) {
console.log(colors[i]);
}
实际上我们只需要数组中元素的值,但是却需要提前获取数组长度,声明索引变量等,尤其是多个循环嵌套的时候,更需要多个索引变量,这样代码的复杂度就会大大增加
为了消除这种复杂度以及减少循环的错误(比如错误使用其他循环中的变量),ES6提供了迭代器和for of循环共同解决这个问题
就是一个具有 next()方法的对象,每次调用next()都会返回一个结果对象,该结果对象有两个属性,value表示当前值,done表示遍历是否结束
ES5的语法创建一个迭代器:
function createIterator(items) {
var i = 0;
return {
next: function() {
var done = i >= item.length;
var value = !done ? items[i++] : undefined;
return {
done: done,
value: value
};
}
};
}
// iterator 就是一个迭代器对象
var iterator = createIterator([1, 2, 3]);
console.log(iterator.next()); // { done: false, value: 1 }
console.log(iterator.next()); // { done: false, value: 2 }
console.log(iterator.next()); // { done: false, value: 3 }
console.log(iterator.next()); // { done: true, value: undefined }
const obj = {
value: 1
};
for (value of obj) {
console.log(value); // error
}
// 给对象添加 Symbol.iterator 属性
const obj = {
value: 1
};
obj[Symbol.iterator] = function() {
return createIterator([1, 2, 3]);
};
for (value of obj) {
console.log(value);
}
// 1
// 2
// 3
for of遍历的其实是对象的 Symbol.iterator属性
const colors = ["red", "green", "blue"];
for (let color of colors) {
console.log(color);
}
// red
// green
// blue
// ES6默认部署了 Symbol.iterator 属性
// 我们可以手动修改这个属性
var colors = ["red", "green", "blue"];
colors[Symbol.iterator] = function() {
return createIterator([1, 2, 3]);
};
for (let color of colors) {
console.log(color);
}
// 1
// 2
// 3
默认部署了 Symbol.iterator 属性的
- 数组
- Set
- Map
- 类数组对象
- Generator对象
- 字符串
- entries(): 返回一个遍历器对象,遍历[键名,键值]组成的数组
- keys(): 返回一个遍历器对象,用来遍历所有的键名
- values(): 返回一个遍历器对象,用来遍历所有的键值