JavaScript-迭代器模式

迭代器模式

顺序访问一个集合
使用者无需知道集合内部结构(封装)

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);
}

设计原则验证

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

原文地址:https://www.cnblogs.com/ygjzs/p/12240147.html

时间: 2024-11-06 09:48:21

JavaScript-迭代器模式的相关文章

JavaScript设计模式 - 迭代器模式

迭代器模式是指提供一种方法顺序访问一个聚合对象中的各个元素,而又不需要暴露该对象的内部表示. 迭代器模式可以把迭代的过程从业务逻辑中分离出来,在使用迭代器模式之后,即使不关心对象的内部构造,也可以按顺序访问其中的每个元素 许多浏览器都支持 Javascript 的 Array.prototype.forEach 迭代器可以分为 内部迭代器 和 外部迭代器 一.jQuery 中的迭代器 1 $.each( [1,2,3,4], function (i, n) { 2 console.log( "当

JavaScript设计模式与开发实践---读书笔记(7) 迭代器模式

迭代器模式是指提供一种方法顺序访问一个聚合对象中的各个元素,而又不需要暴露该对象的内部表示. JavaScript中的Array.prototype.foreach. 1.JQuery中的迭代器 $.each函数 2.自己实现一个each函数 var each = function(ary,callback){ for(var i=0,l=ary.length;i<l;i++){ callback.call(ary[i],i,ary[i]);//把下标和元素当作参数传给callback函数 }

javascript设计模式与开发实践阅读笔记(7)——迭代器模式

迭代器模式:指提供一种方法顺序访问一个聚合对象中的各个元素,而又不需要暴露该对象的内部表示. 迭代器模式可以把迭代的过程从业务逻辑中分离出来,在使用迭代器模式之后,即使不关心对象的内部构造,也可以按顺序访问其中的每个元素. 流行语言如Java.Ruby 等都已经有了内置的迭代器实现,许多浏览器也支持JavaScript的Array.prototype.forEach. jQuery中的迭代器 1 $.each( [1, 2, 3], function( i, n ){ 2 console.log

深入理解JavaScript系列(35):设计模式之迭代器模式

介绍 迭代器模式(Iterator):提供一种方法顺序一个聚合对象中各个元素,而又不暴露该对象内部表示. 迭代器的几个特点是: 1.访问一个聚合对象的内容而无需暴露它的内部表示. 2.为遍历不同的集合结构提供一个统一的接口,从而支持同样的算法在不同的集合结构上进行操作. 3.遍历的同时更改迭代器所在的集合结构可能会导致问题(比如C#的foreach里不允许修改item). 正文 一般的迭代,我们至少要有2个方法,hasNext()和Next(),这样才做做到遍历所有对象,我们先给出一个例子: v

JavaScript设计模式与开发实践 迭代器模式

迭代器模式是指提供一种方法顺序访问一个聚合对象中的各个元素,而又不需要暴露该对象的内部表示.迭代器模式可以把迭代的过程从业务逻辑中分离出来,在使用迭代器模式之后,即使不关心对象的内部构造,也可以按顺序访问其中的每个元素. 一.内部迭代器和外部迭代器 1. 内部迭代器 内部迭代器函数的内部已经定义好了迭代规则,它完全接手整个迭代过程,外部只需要一次初始调用. 内部迭代器在调用的时候非常方便,外界不用关心迭代器内部的实现,跟迭代器的交互也仅仅是一次初始调用,但这也刚好是内部迭代器的缺点. var e

javascript设计模式学习之七——迭代器模式

一.迭代器模式定义 迭代器模式提供一种方法顺序访问一个聚合对象中的各个元素,并且不需要暴露该对象的内部表示. 在当前大部分语言中,都已经内置了迭代器模式.迭代器有内部迭代器和外部迭代器之分,一般现有语言中实现的大多是内部迭代器. 二.jquery中的each实现 //类似jquery中的each迭代器 $.each=function(obj,callback){ var value, i=0, isArray=isArrayLike(obj), length=obj.length; if(isA

JavaScript设计模式与开发实践-第7章-迭代器模式

迭代器模式的定义:提供一种方法访问一个聚合对象中的各个对象.可以做到不关心对象的内部构造,也可以按顺序的访问每个原宿. 内部迭代器:外部只需要一次初始调用 1 var each = function( ary, callback ){ 2 for (var i = 0; i < ary.length; i++) { 3 callback.call( ary[i], i, ary[i] ); 4 }; 5 } 6 7 // 只进行了这一次调用 8 each( [ 1, 2, 3 ], functi

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

迭代器模式提供一种方法顺序访问一个聚合对象中各个元素,而又不需要暴露该方法中的内部表示. jQuery中我们经常会用到一个each函数就是迭代器模式 作用 为遍历不同的集合结构提供一个统一的接口,从而支持同样的算法在不同的集合结构上进行操作 对于集合内部结果常常变化各异,我们不想暴露其内部结构的话,但又想让客户代码透明的访问其中的元素,这种情况下我们可以使用迭代器模式. 注意事项 一般的迭代,我们至少要有2个方法,hasNext和Next,这样才做到遍历所有对象. 遍历的同时更改迭代器所在的集合

设计模式之迭代器模式

介绍 迭代器模式(Iterator):提供一种方法顺序一个聚合对象中各个元素,而又不暴露该对象内部表示. 迭代器的几个特点是: 访问一个聚合对象的内容而无需暴露它的内部表示. 为遍历不同的集合结构提供一个统一的接口,从而支持同样的算法在不同的集合结构上进行操作. 遍历的同时更改迭代器所在的集合结构可能会导致问题(比如 C# 的 foreach 里不允许修改 item). 正文 一般的迭代,我们至少要有 2 个方法,hasNext()和 Next(),这样才做做到遍历所有对象,我们先给出一个例子:

设计模式之三:迭代器模式(IteratorPattern)

迭代器(Iterator)模式,又叫游标(Cursor)模式.其定义为:提供一种方法访问一个容器对象中各个元素,而又不需暴露该对象的内部细节.迭代器模式是和容器相关的,对容器对象的访问设计到遍历算法. 迭代器模式由以下角色组成: 迭代器角色(Iterator):迭代器角色负责定义访问和遍历元素的接口. 具体迭代器角色(Concrete Iterator):具体迭代器角色要实现迭代器接口,并记录遍历中的当前位置. 容器角色(Container):容器角色负责提供创建具体迭代器角色的接口. 具体容器