(十一)迭代器模式
迭代器模式
- 迭代器模式
- 迭代器模式 介紹
- 概念
- 示例
- 迭代器模式 演示
- 迭代器模式 場景
- jQuery each
- ES6 Iterator
- ES6 Iterator為何存在?
- ES6 是什么?
- 迭代器模式 總結
迭代器模式
- 介紹
- 演示
- 場景
- 總結
迭代器模式 介紹
- 順序訪問一個集合
- 使用者無需知道集合的內部結構(封裝)
概念
這種模式用于順序訪問集合對象的元素,不需要知道集合對象的底層表示。
示例
沒有找到合適的例子,就以一個常用的 jQuery 為示例吧。
<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.lengthfor (i = 0; i < length; i++) {console.log(nodeList[i])}// 第三$p.each(function (key, p) {console.log(key, p)}) </script>如何能寫出一個方法來遍歷這三種對象呢?
// 如何能寫出一個方法來遍歷這三種對象呢? function each(data) {var $data = $(data) // 生成迭代器$data.each(function (key, p) {console.log(key, p)}) }// 測試代碼 each(arr) each(nodeList) each($p)//順序遍歷有序集合 //使用者不必知道集合的內部結構其中var $data = $(data)就是一個迭代器 ,它可以以統(tǒng)一的方式訪問內部結構,但是不需要知道內部結構是什么。這就是迭代器模式的主要思想。
迭代器模式 演示
先看下傳統(tǒng)的 UML 類圖
簡化之后的 UML 類圖
代碼演示如下。大家不必驚訝于:為何一個簡單的數(shù)組不直接遍歷而是費勁如此周折?其實:
- 設計模式應用小 demo 本身就會變得更加復雜,讓人費解,這很正常
- 該示例是演示如何生成迭代器,故而將數(shù)組生成迭代器再遍歷,而不是直接遍歷
迭代器模式 場景
jQuery each
// 如何能寫出一個方法來遍歷這三種對象呢? function each(data) {var $data = $(data) // 生成迭代器$data.each(function (key, p) {console.log(key, p)}) }// 測試代碼 each(arr) each(nodeList) each($p)//順序遍歷有序集合 //使用者不必知道集合的內部結構ES6 Iterator
ES6 Iterator為何存在?
- ES6語法中,有序集合的數(shù)據(jù)類型已經有很多
- Array Map Set String TypedArray 函數(shù)中的arguments NodeList
- 需要有一個統(tǒng)一的遍歷接口來遍歷所有數(shù)據(jù)類型
- (注意,object不是有序集合,可以用Map代替)
ES6 是什么?
- 以上數(shù)據(jù)類型,都有[Symbol iterator]屬性
- 屬性值是函數(shù),執(zhí)行函數(shù)返回一個迭代器,即Iterator類型
- 這個迭代器就有next方法可順序迭代子元素
- 可運行Array.prototype[Symbol.iterator]來測試,在 chrome 控制臺中運行Array.prototype[Symbol.iterator]看下,返回的是不是一個函數(shù)。
有一個問題,Symbol.iterator并不是人人都知道,而且這么讓大家用,每個人都需要封裝一個each函數(shù),相當不人人性化 —— ES6 當然知道這個問題,于是就有了for...of語法。但是你要明白,這個語法最終依賴的還是 ES6 Iterator ,是基于迭代器模式的。
// `Symbol.iterator` 并不是人人都知道 // 也不是每個人都需要封裝一個 each 方法 // 因此有了 `for...of` 語法 function each(data) {//for...in訪問數(shù)組,for...of訪問帶有遍歷特性的對象//帶有遍歷特性的對象,data[Symbol iterator]有值for (let item of data) {console.log(item)} }each(arr) each(nodeList) each(m)說明: Object 不是有序即可,如果想要 Object 的遍歷器功能,可以使用 Map
Iterator 的價值不限于上述幾個類型的遍歷
還有Generator的使用
即只要返回的數(shù)據(jù)符合 Iterator 接口的要求
即可使用Iterator 語法,這就是迭代器模式
當然也可以用for...of
function* foo() {yield 1;yield 2;yield 3;yield 4;yield 5;return 6; }// 當然也可以用`for...of` for (let v of foo()) {console.log(v); }(以上代碼放在 nodejs 環(huán)境下運行) Generator 的語法和應用是另外一部分知識,此處就不展開講解了,拿來只是為了理解迭代器模式的設計思想。
迭代器模式 總結
- 什么是迭代器模式
- 核心:是創(chuàng)建一個迭代器對象或者接口,用于迭代數(shù)據(jù),使用者和具體數(shù)據(jù)分離
- JS 中的場景
設計原則驗證:
- 迭代器對象和目標對象分離
- 迭代器將使用者與目標對象隔離開
- 符合開放封閉原則
總結
- 上一篇: 游戏里dps是什么意思 4399小游戏
- 下一篇: 小米商城app怎么看直播(小米官方售后服