迭代器模式

顺序访问一个集合

使用者无需知道集合内部结构(封装)

jQuery 示例

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>Document</title>
</head>
<body>
<p>jquery each</p>
<p>jquery each</p>
<p>jquery each</p> <script src="https://cdn.bootcss.com/jquery/3.3.1/jquery.js"></script>
<script>
var arr = [1, 2, 3];
var nodeList = document.getElementsByTagName("p");
var $p = $("p"); // 要对这三个变量进行遍历,需要写三个遍历方法
// 第一
arr.forEach(function(item) {
console.log(item);
});
// 第二
var i,
length = nodeList.length;
for (i = 0; i < length; i++) {
console.log(nodeList[i]);
}
// 第三
$p.each(function(key, p) {
console.log(key, p);
}); // 如何能写出一个方法来遍历这三个对象呢
function each(data) {
var $data = $(data);
$data.each(function(key, p) {
console.log(key, p);
});
}
each(arr);
each(nodeList);
each($p);
</script>
</body>
</html>

传统 UML 类图

javascript 中的 UML 类图

class Iterator {
constructor(conatiner) {
this.list = conatiner.list;
this.index = 0;
}
next() {
if (this.hasNext()) {
return this.list[this.index++];
}
return null;
}
hasNext() {
if (this.index >= this.list.length) {
return false;
}
return true;
}
} class Container {
constructor(list) {
this.list = list;
}
getIterator() {
return new Iterator(this);
}
} // 测试代码
let container = new Container([1, 2, 3, 4, 5]);
let iterator = container.getIterator();
while (iterator.hasNext()) {
console.log(iterator.next());
}

使用场景

jQuery each

上面的 jQuery 代码就是

ES6 Iterator

ES6 Iterator 为何存在?

  • es6 语法中,有序集合的数据类型已经有很多了
  • Array Map Set String TypedArray argument Nodelist
  • 需要有一个统一的遍历接口来遍历所有的数据类型
  • (注意,object 不是有序集合,可以用 Map 代替)

es6 Interator 是什么?

  • 以上数据类型,都有[Symbol.iterator]属性
  • 属性值是函数,执行函数返回一个迭代器
  • 这个迭代器就有 next 方法可以顺序迭代子元素
  • 可运行 Array.prototype[Symbol.iterator]来测试

示例

let arr = [1, 2, 3, 4]
let nodeList = document.getElementsByTagName('p')
let m = new Map()
m.set('a', 100)
m.set('b', 200) function each(data) {
// 生成遍历器
let iterator = data[Symbol.iterator]() console.log(iterator.next()) // 有数据时返回 {value: 1, done: false}
console.log(iterator.next())
console.log(iterator.next())
console.log(iterator.next())
console.log(iterator.next()) // 没有数据时返回 {value: undefined, done: true} each(arr)
each(nodeList)
each(m)

上面代码改进

let arr = [1, 2, 3, 4];
let nodeList = document.getElementsByTagName("p");
let m = new Map();
m.set("a", 100);
m.set("b", 200); function each(data) {
// 生成遍历器
let iterator = data[Symbol.iterator](); let item = { done: false };
while (!item.done) {
item = iterator.next();
if (!item.done) {
console.log(item.value);
}
}
} each(arr);
each(nodeList);
each(m);

es6 很聪明提供了for of

let arr = [1, 2, 3, 4];
let nodeList = document.getElementsByTagName("p");
let m = new Map();
m.set("a", 100);
m.set("b", 200); function each(data) {
for (let item of data) {
console.log(item);
}
} each(arr);
each(nodeList);
each(m);

ES6 Interator 与 Generator

  • Interator 的价值不限于上述几个类型的遍历
  • 还有 Generator 函数的使用
  • 即只要返回的数据符合 Interator 接口的要求

function* helloWorldGenerator() {
yield "hello";
yield "world";
return "ending";
} var hw = helloWorldGenerator();
console.log(hw.next());
console.log(hw.next());
console.log(hw.next());
console.log(hw.next()); //输出
// { value: 'hello', done: false }
// { value: 'world', done: false }
// { value: 'ending', done: true }
// { value: undefined, done: true }
function* foo() {
yield 1;
yield 2;
yield 3;
yield 4;
yield 5;
return 6;
} for (let v of foo()) {
console.log(v);
}

设计原则验证

  • 迭代器对象和目标对象分离
  • 迭代器将使用者与目标者对象隔离开
  • 符合开放封闭原则

最新文章

  1. 浏览器下载/导出文件 及jQuery表单提交
  2. eclipse远程调试Hadoop
  3. hibernate(五) hibernate一对一关系映射详解
  4. TypeScript Modules(模块)
  5. React Native组件之Text
  6. TortoiseSVN-1.8.11 安装时弹出2503错误导致安装失败解决办法
  7. mac基本用法
  8. jquery 在 table 中修改某行值
  9. Java编程思想学习(四) 访问权限
  10. chattr实现文件不可删除
  11. html系列教程--header head iframe img
  12. 洛谷P1446 [HNOI2008]Cards
  13. javascript 表达式
  14. carthage和cocoapods
  15. Build Tool/Maven, Gradle
  16. 什么是JDK?什么是JRE?JDK与JRE的区别和用途
  17. input reset 重置时间
  18. POI 生成excel(大数据量) SXSSF
  19. SCOI 2018 划水记
  20. 关于sql链接超时的问题

热门文章

  1. Java框架之SpringMVC 05-拦截器-异常映射-Spring工作流程
  2. 优雅写Java之二(数组集合流)
  3. idea搭建springmvc(maven版)
  4. CTF--HTTP服务--SSI注入
  5. VirtualBox 虚拟机 从入门到入坑
  6. java.net.UnknownHostException 异常处理(个人案例)
  7. python学习Day04--列表
  8. C语言寒假大作战03
  9. 遍历CSDN博客
  10. 关于RiscV的一些资料整理