迭代器模式

是指提供一种方法顺序访问一个聚合对象中的各个元素,而又不需要暴露该对象的内部表示。

js有许多迭代器模式实现,比如说forEach,es6的yield

1. 内部迭代器和外部迭代器

1.1 内部迭代器

内部定义好迭代规则,外部只需要一次初始调用

比如说jquery的$.each,以及js的for...of

1.2 外部迭代器

显示的请求迭代下一个元素,迭代流程由外部控制

比如说es6的迭代器yield

2. 实现一个$.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
function each(obj, callback) {
let length, i = 0;
// 判断是否为类数组对象
if (isArrayLike(obj)) {
length = obj.length;
for (; i < length; i++) {
// 如果回调函数放回false,中断迭代器
if (callback.call(obj[i], i, obj[i]) === false) {
break;
}
}
} else {
for (i in obj) {
if (callback.call(obj[i], i, obj[i]) === false) {
break;
}
}
}

return obj
}

let data = { 0: "a", 1: "b", length: 2 }
each(data, (key, val) => {
console.log(key, val);
// 0 a
// 1 b
});

3. 手动实现es6的简易迭代器

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
// 定义生成器函数,入参是任意集合
function iteratorGenerator(list) {
// idx记录当前访问的索引
let idx = 0;
// len记录传入集合的长度
const len = list.length;
return {
// 自定义next方法
next: function() {
// 如果索引还没有超出集合长度,done 为 false
const done = idx >= len;
// 如果done为false,则可以继续取值
const value = !done ? list[idx++] : undefined;

// 将当前值与遍历是否完毕(done)返回
return {
done: done,
value: value
}
}
}
}

参考

《javascript设计模式与开发实践》
JavaScript 设计模式核⼼原理与应⽤实践

作者

Liang

发布于

2021-02-01

更新于

2021-12-25

许可协议


评论