[TOC]
# 迭代器模式
是指提供一种方法顺序访问一个聚合对象中的各个元素,而又不需要暴露该对象的内部表示。
## 实现自己的迭代器
```javascript
var each = function(arr, callback){
for(var i=0, l=arr.length, i < l, i++){
callback(i, arr[i]);
}
};
each(['a','b','c'], function(i, val){
console.log(val);
});
// a, b, c
```
## 内部迭代器和外部迭代器
### 内部迭代器
上面的`each`就属于内部迭代器,函数内部已经定义好了迭代规则,它完全接手了整个迭代过程,外部只需要一次调用。
### 外部迭代器
外部迭代器必须显式地请求迭代一个元素。
```javascript
var Iterator = function(obj){
var current = 0;
var next = function(){
current += 1;
}
var isDone = function(){
return current > obj.length;
}
var getCurrentItem = function(){
return obj[current];
}
return {
next: next,
isDone: isDoen,
getCurrentItem: getCurrentItem,
length: obj.length
}
};
// 改写对比函数
var compare = function(iterator1, iterator2){
if(iterator1.length !== iterator2.length){
throw new Error('不相等');
}
while(!iterator1.isDone() && !iterator2.isDone()){
if(iterator1.getCurrentItem() !== iterator2.getCurrentItem()){
thriw new Error('不相等')
}
iterator1.next();
iterator2.next();
}
alert('相等')
};
var iterator1 = Iterator([1,2,3]);
var iterator2 = Iterator([1,2,4]);
compare(iterator1, iterator2);
```
## 迭代类数组对象和字面量对象
jQuery中的`$.each`实现
```javascript
$.each = function(obj, callback){
var value,
i = 0,
length = obj.length;
isArray = isArraylike(obj);
if(isArray){ // 迭代类数组
for( ; i<length; i++){
value = callback(obj[i], i);
if(value === false){
break; // 中止迭代器
}
}
}else{
for( i in obj ){ // 迭代字面量对象
value = callback(obj[i], i);
if(value === false){
break;
}
}
}
};
```
## 倒序迭代器
```javascript
var reverseEach = function(arr, callback){
for(var l=ary.length-1, l>=0; l--){
callback(l, ary[l]);
}
};
reverseEach([0,1,2], function(i, n){
console.log(n);
});
// 2,1,0
```
## 中止迭代器
如果函数的返回值为`false`则`break`
```javascript
$.each = function(obj, callback){
var value,
i = 0,
length = obj.length;
isArray = isArraylike(obj);
if(isArray){ // 迭代类数组
for( ; i<length; i++){
value = callback(obj[i], i);
if(value === false){
break; // 中止迭代器
}
}
}else{
for( i in obj ){ // 迭代字面量对象
value = callback(obj[i], i);
if(value === false){
break;
}
}
}
};
```