0%

JavaScript设计模式--迭代器模式

迭代器模式是指提供一种方法顺序访问一个聚合对象中的各个元素,而又不需要暴露该对象的内部表示。大部分现代语言都已经在语言层面实现了迭代器。比如在JavaScript中的Array.prototype.forEach

each函数

1
2
3
4
5
6
7
8
9
var each=function(ary,callback){
for(let i=0;i<ary.length;i++){
return callback.call(ary[i],i,ary[i])
}
}

each([1,2,3],function(i,n){
alert([i,n])
})

内部迭代器/外部迭代器

内部迭代器:迭代规则被写入迭代器中,无法根据情况改变,只需一次地调用。
外部迭代器:每次调用会得到下一个元素,但是需要显示地调用。
上文中的each就是一个内部迭代器。
外部迭代器举例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
var Iterater=function(obj){
var cur=0;
var isDone=function(){
return cur>==obj.length
}
var next=function(){
cur+=1;
return isDone()?"done":obj[cur];
}
return{
nexxt:next,
isDone:isDone
}
}
var iterater1=Iterater([1,2,3])

iterater1.next();//1
iterater1.next();//2
iterater1.next();//3
iterater1.next();//"done"

Jquery中的 迭代器

jQuery提供了$.each函数来封装各种迭代行为

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
var isWindow = function(obj){
return obj != null && obj == obj.window;
//window对象有个window属性指向自己
}

var isArrayLike = function(obj){
var length = obj.length,
type = $.type(obj);
if(type == 'function' || $.isWindow(obj) ){
return false;
}
if(obj.nodeType == 1 && length){
return true;
}

return type === 'array' || length === 0 || typeof length === 'number' && length > 0 && (length - 1) in obj;
}

$.each=function(obj,callback){
var value,
i=0,
length=obj.length,
isArray=isArraylike(obj);
if(isArray){
for(;i<length;i++){
value=callback.call(obj[i],i,obj[i]);
if(value===false){
break;
}
}
}else{
for(i in obj){
value=callback.call(obj[i],i,obj[i]);
if(value===false){
break;
}
}
}
return obj;
}

应用

当我们需要针对不同的环境做出相应的反应时,比如选择不同的策略,我们可以使用迭代器将各种策略封装为可迭代对象,一旦某种策略执行成功,即退出迭代,这样可以省去许多的判断分支逻辑。