Skip to content

Commit a25cd6c

Browse files
committed
迭代器模式
1 parent ef8e57b commit a25cd6c

File tree

1 file changed

+187
-0
lines changed

1 file changed

+187
-0
lines changed

seven-chapter/each.js

+187
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,187 @@
1+
// 迭代器模式是指提供一种方法顺序访问一个聚合对象中的各个元素,
2+
// 而又不需要暴露该对象的内部表示。
3+
// 迭代器模式可以把迭代的过程从业务逻辑中分离出来,在使用迭代器模式之后,
4+
// 迭代器模式,使不关心对象的内部构造,也可以按顺序访问其中的每个元素
5+
6+
// each (array,callback)
7+
8+
var each = function (array,calback) {
9+
for(var i=0;i<array.length;i++){
10+
callback.call(array,i,array[i])
11+
}
12+
}
13+
14+
each([1,2,3,4],function(i,n){
15+
console.log([i,n]);
16+
})
17+
18+
//内部迭代器,外部迭代器
19+
//each 函数属于内部迭代器,each 函数的内部已经定义好了迭代规则
20+
//由于内部迭代器的迭代规则已经被提前规 定,上面的 each 函数就无法同时迭代 2 个数组了
21+
22+
var compare = function(array1,array2){
23+
if(array1.length !== array2.length){
24+
throw new Error('array1 array2 not equal')
25+
}
26+
27+
each(array1,function(i,n){
28+
if(n !== array2[i]){
29+
throw new Error('array1 array2 not equal')
30+
}
31+
})
32+
33+
console.log('array1 array2 equal')
34+
}
35+
36+
//外部迭代器
37+
// 外部迭代器必须显式地请求迭代下一个元素
38+
// 外部迭代器增加了一些调用的复杂度,但相对也增强了迭代器的灵活性,我们可以手工控制 迭代的过程或者顺序
39+
40+
var Iterator = function(obj){
41+
var current = 0;
42+
var next = function(){
43+
current +=1;
44+
}
45+
46+
var isDone = function(){
47+
return current > obj.length;
48+
}
49+
50+
var getCurrItem = function(){
51+
return obj[current]
52+
}
53+
54+
return {
55+
next:next,
56+
isDone:isDone,
57+
getCurrItem:getCurrItem
58+
}
59+
}
60+
61+
var compare = function(iterator1,iterator2){
62+
while(!iterator1.isDone() && !iterator2.isDone()){
63+
if(iterator1.getCurrItem() !== iterator2.getCurrItem()){
64+
throw new Error('iterator1 iterator2 not equal')
65+
}
66+
67+
iterator1.next()
68+
iterator2.next()
69+
}
70+
console.log('iterator1 iterator2 equal')
71+
}
72+
73+
var iterator1 = Iterator([1,2,3])
74+
var iterator2 = Iterator([1,2,3])
75+
76+
compare(iterator1,iterator2)
77+
78+
79+
//迭代数组对象和字面量对象
80+
// 迭代的聚合对象拥有 length 属性而且可以用下标访问,那它就可以被迭代
81+
$.each = function(obj,callback){
82+
var value,
83+
i = 0,
84+
length = obj.length,
85+
isArray = isArrayLike(obj);
86+
87+
if(isArray){
88+
for(;i<length;i++){
89+
value = callback.call(obj[i],i,obj[i])
90+
91+
if(value === false){
92+
break;
93+
}
94+
}
95+
}else{
96+
for(i in obj){
97+
value = callback.call(obj[i],i,obj[i]);
98+
if(value === false){
99+
break;
100+
}
101+
}
102+
}
103+
return obj;
104+
}
105+
106+
//倒序迭代器
107+
var reverseEach = function(array,callback){
108+
for(var l= array.length -1 ; l>=0; l--){
109+
callback.call(array,l,array[l])
110+
}
111+
}
112+
113+
reverseEach( [ 0, 1, 2 ], function( i, n ){
114+
console.log( n ); // 分别输出:2, 1 ,0
115+
});
116+
117+
//中止迭代器
118+
var each = function(array,callback){
119+
for(var i=0;i<array.length;i++){
120+
if(callback.call(array,i,array[i]) === false){
121+
break;
122+
}
123+
}
124+
}
125+
126+
each([1,2,3,4,5],function(i,n){
127+
if(n > 3){
128+
return false;
129+
}
130+
console.log(n);
131+
})
132+
133+
//迭代器应用举例
134+
// 根据不同的浏览器获取相应的上传组件对象
135+
136+
var getUploadObj = function(){
137+
try{
138+
return new ActiveXObject('TXFINActiveX.FTNUpload')
139+
}catch(e){
140+
if(supportFlash()){
141+
var str = '<object type="application/x-shockwave-flash"></object>'
142+
return $(str).appendTo($('body'))
143+
}else{
144+
var str = '<input name="file" type="file" />'
145+
return $(str).appendTo($('body'))
146+
}
147+
}
148+
149+
}
150+
151+
//我们把每种获取 upload 对象的方法都封装在各自的函数里,
152+
// 然后使用一个迭代器, 迭代获取这些 upload 对象,直到获取到一个可用的为止
153+
var getActiveUploadObj = function(){
154+
try{
155+
return new ActiveXObject('TXFINActiveX.FTNUpload')
156+
}catch(e){
157+
return false;
158+
}
159+
}
160+
161+
var getFlashUploadObj = function(){
162+
if(supportFlash()){
163+
var str = '<object type="application/x-shockwave-flash"></object>'
164+
return $(str).appendTo($('body'))
165+
}
166+
return false;
167+
}
168+
169+
var getFormUploadObj = function(){
170+
var str = '<input name="file" type="file" />'
171+
return $(str).appendTo($('body'))
172+
}
173+
174+
var iteratorUploadObj = function(){
175+
for(var i=0,fn;fn=[arguments[i++]];){
176+
var uploadObj = fn()
177+
if(uploadObj !== false){
178+
return uploadObj;
179+
}
180+
}
181+
}
182+
183+
var getWebkitUploadObj = function(){};
184+
var getHtml5UploadObj = function(){};
185+
186+
var uploadObj = iteratorUploadObj( getActiveUploadObj, getFlashUploadObj, getFormUpladObj );
187+

0 commit comments

Comments
 (0)