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

内容大部分来自 《javascript 设计模式与开发实践》一书,适当的结合自己工作实践,做出整理和笔记
系列: javascript 设计模式

迭代器模式

迭代器模式:提供一种方法顺序访问一个聚合对象中的各个元素,而又不暴露该对象的内部方法,大部分的编程语言都原生支持,Js的Array forEach

内部迭代器

使用方便,不用关注内部实现,例如js forEach

1
2
3
4
5
6
7
const each = function each(ary, callback) {
for (let i = 0, l = ary.length; i < l; i++) {
if (callback.call(ary[i], i, ary[i]) === false) {
break;
}
}
};

外部迭代器

复杂度会相对高一点,单是相对增强了迭代器的灵活性,在 js 中并不常用,如下形式:

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
// 外部迭代器,javascript 中很少用
const iterator = function iterator(obj) {
let current = 0;

const next = function next() {
current += 1;
};

const isDone = function isDone() {
return current >= obj.length;
};

const getCurrentItem = function getCurrentItem() {
return obj[current];
};

return {
next,
isDone,
getCurrentItem
};
};

// 基于外部迭代器的 compare 函数实现
const compare = function compare(iterator1, iterator2) {
while (!iterator1.isDone() && !iterator2.isDone()) {
if (iterator1.getCurrentItem() !== iterator2.getCurrentItem()) {
throw new Error('不相等');
}
iterator1.next();
iterator2.next();
}
console.log('相等');
};

const iterator1 = iterator([1, 2, 3]);
const iterator2 = iterator([1, 2, 3]);

compare(iterator1, iterator2);

内部和外部两种迭代器没有好坏之分,使用可以根据场景而定。

中止迭代器

类似于 Array.some return true 后会中止循环

迭代器模式的实际应用举例

需要获取同一个方法,要多种条件判断的时候,如下例子:

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
41
42
43
// 获取某个对象,充斥着各种判断,当要扩展的时候也需要再去修改获取方法,违反了开放封闭原则
function getXxObj() {
if (window.xxx) {
return new A();
} else if (window.xxxx) {
return new B();
}
return new C();
}

// 修改后
function getA() {
if (window.xx) {
return new A();
}
return false;
}

function getB() {
if (window.xx) {
return new B();
}

return false;
}

function getC() {
console.log('this ok');
return new C();
}

// 按顺序依次判断是否适用
const useObj = (() => {
let resObj = null;
[getA, getB, getC].some(item => {
const curItem = item();
if (curItem) {
resObj = item;
return true;
}
})
return resObj;
})();

小结

迭代器模式在大部分编程语言都是内置的,在如上的选择一个合适的场景对象时还是适用的,可以轻松做到开放封闭,有助于代码维护。