JavaScript-迭代器模式

来源:https://www.cnblogs.com/ygjzs/archive/2020/01/29/12240147.html
-Advertisement-
Play Games

迭代器模式 順序訪問一個集合 使用者無需知道集合內部結構(封裝) jQuery 示例 傳統 UML 類圖 javascript 中的 UML 類圖 使用場景 jQuery each 上面的 jQuery 代碼就是 ES6 Iterator ES6 Iterator 為何存在? es6 語法中,有序集 ...


迭代器模式

順序訪問一個集合
使用者無需知道集合內部結構(封裝)

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

設計原則驗證

  • 迭代器對象和目標對象分離
  • 迭代器將使用者與目標者對象隔離開
  • 符合開放封閉原則

您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 首先官網(http://www.ruby-lang.org/en/downloads/)下載 ruby (1)打開鏈接進入到下載頁面,點擊如下位置進行下載 (2)下載頁面 (3)進入到各個版本的列表頁 安裝 sass(1)在開始菜單輸入“start”會出現“Start Command Prompt ...
  • 一、過渡模塊的基本使用 1.*:hover;這個偽類選擇器除了可以用在a標簽上,還可以用在其他任何標簽上。 2.過渡三要素: (1)必須要有屬性發生變化;(2)必須告訴系統哪個屬性需要執行過渡效果;(3)必須告訴系統過渡效果持續的時長。 3.註意點: 當多個屬性需要同時執行過渡效果的時候,可以使用英 ...
  • 1.新建js文件 utils.js,自定義方法 let local = { say() { console.log('我是插件裡面自定義的方法') } } export default { install: function(vm) { vm.prototype.$local = local } } ...
  • v-for: v-for 指令需要以 site in sites 形式的特殊語法, sites 是源數據數組並且 site 是數組元素迭代的別名。 demo1. <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title></title> ...
  • 一、故事背景: 1. 今天公司有個項目需求 2. 在前端頁面實現一個倒計時功能 3. 初步設想:後端根據需求規定一個未來的時間,前端根據當前時間進行計算 4. 然後將時間格式化,時分秒的格式 5. 時間倒計時完成,刷新頁面獲取最新的頁面 6. 最後在前端展示;大致是這樣 二、上代碼 <!DOCTYP ...
  • node 的`fs`文檔密密麻麻的 api 非常多,畢竟全面支持對文件系統的操作。文檔組織的很好,操作基本分為文件操作、目錄操作、文件信息、流這個大方面,編程方式也支持同步、非同步和 Promise。 本文記錄了幾個文檔中沒詳細描寫的問題,可以更好地串聯`fs`文檔思路: - 文件描述符 - ... ...
  • 其他設計模式 JavaScript 中不常用 對應不到經典場景 原型模式 行為型 clone 自己,生成一個新對象 java 預設有 clone 介面,不用自己實現 對比 js 中的原型 prototype prototype 可以理解為 es6 class 的一種底層原理 而 class 是實現面 ...
  • 狀態模式 一個對象有狀態變化 每次狀態變化都會觸發一個邏輯 不能總是用 if...else 來控制 示例:交通信號燈的不同顏色變化 傳統的 UML 類圖 javascript 中的 UML 類圖 javascript class State { constructor(color) { this.c ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...