自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

教你優(yōu)雅的使用迭代器模式以及案例復(fù)盤

開發(fā) 前端
迭代器模式主要的思想就是在不暴露對(duì)象內(nèi)部結(jié)構(gòu)的同時(shí)可以按照一定順序訪問(wèn)對(duì)象內(nèi)部的元素。

眼看新的一年又來(lái)了,為了提高程序員的幸福指數(shù), 我覺(jué)得設(shè)計(jì)模式還是非常有必要好好復(fù)盤一下的. 筆者基于工作中的總結(jié)和提煉,為了提高團(tuán)隊(duì)代碼質(zhì)量和可維護(hù)性,特意寫了幾篇設(shè)計(jì)模式的文章,供大家參考和學(xué)習(xí)。

你將學(xué)到

  • 迭代器模式的含義
  • 實(shí)現(xiàn)一個(gè)數(shù)組迭代器
  • 實(shí)現(xiàn)一個(gè)對(duì)象迭代器
  • 實(shí)現(xiàn)路徑查找/賦值迭代器
  • 如何用迭代器的思想解決分支循環(huán)嵌套問(wèn)題
  • 實(shí)現(xiàn)一個(gè)圖片播放器

正文

1.迭代器的含義

  • 迭代器模式主要的思想就是在不暴露對(duì)象內(nèi)部結(jié)構(gòu)的同時(shí)可以按照一定順序訪問(wèn)對(duì)象內(nèi)部的元素。

其實(shí)javascript中的很多方法都運(yùn)用了迭代器的思想,比如數(shù)組的forEach,every,find,some,map,entries等等,這些操作極大的簡(jiǎn)化了我們的邏輯操作,接下來(lái)我們就來(lái)看看它的具體應(yīng)用吧。

2.實(shí)現(xiàn)一個(gè)數(shù)組迭代器

我們都知道javascript中數(shù)組的forEach方法,那么不用這個(gè)方法,我們能自己實(shí)現(xiàn)一個(gè)嗎?

  1. // 數(shù)組迭代器 
  2. let eachArr = function(arr, fn) { 
  3.     let i = 0, 
  4.     len = arr.length; 
  5.     for(; i < len; i++) { 
  6.         if(fn.call(arr[i], i, arr[i]) === false) { 
  7.             break; 
  8.         } 
  9.     } 
  10.  
  11. // 使用 
  12. eachArr([1,2,3,4], (index, value) => { console.log(index, value) }) 

3.實(shí)現(xiàn)一個(gè)對(duì)象迭代器

對(duì)象迭代器和數(shù)組迭代器類似, 只是傳參不同,如下:

  1. // 對(duì)象迭代器 
  2. let eachObj = function(obj, fn) { 
  3.     for(let key in obj) { 
  4.         if(fn.call(obj[key], key, obj[key]) === false) { 
  5.             break; 
  6.         } 
  7.     } 
  8.  
  9. // 使用 
  10. eachObj({a: 11, b: 12}, (key, value) => { console.log(key, value) }) 

4.實(shí)現(xiàn)路徑查找/賦值迭代器

有時(shí)候我們操作對(duì)象的某些屬性時(shí),我們不知道服務(wù)器端是否將該屬性或者該屬性的上級(jí)屬性正確的返回給我們,這個(gè)時(shí)候我們直接通過(guò)點(diǎn)語(yǔ)法或者[]語(yǔ)法直接訪問(wèn)會(huì)導(dǎo)致代碼報(bào)錯(cuò),因此需要我們每一層操作都要做安全校驗(yàn),這樣會(huì)產(chǎn)生大量臃腫代碼,比如:

  1. let obj = {}; 
  2. // 獲取 obj.num.titNum 
  3. let titNum = obj.num.titNum;    // 報(bào)錯(cuò) 
  4. let titNum = obj && obj.num && obj.num.titNum;   // 正確 

我們通過(guò)迭代器可以極大的減少這種校驗(yàn),實(shí)現(xiàn)更健壯的代碼模式:

  1. let findObjAttr = function(obj, key){ 
  2.     if(!obj || !key) { 
  3.         return undefined 
  4.     } 
  5.     let result = obj; 
  6.     key = key.split('.'); 
  7.     for(let i =0; len = key.length; i< len; i++) { 
  8.         if(result[key[i]] !== undefined) { 
  9.             result = result[key[i]] 
  10.         }else { 
  11.             return undefined 
  12.         } 
  13.     } 
  14.     return result 
  15. // 使用 
  16. let a = { b: { c: { d: 1 } } }; 
  17. findObjAttr(a, 'a.b.c.d')     // 1 

這種方式是不是有點(diǎn)類似于lodash的對(duì)象/數(shù)組查找器呢?同理,我們也可以實(shí)現(xiàn)路徑賦值器,如下所示:

  1. let setObjAttr = function(obj, key, value){ 
  2.     if(!obj) { 
  3.         return false 
  4.     } 
  5.     let result = obj, 
  6.     key = key.split('.'); 
  7.     for(let i =0, len = key.length; i< len - 1; i++){ 
  8.         if(result[key[i]] === undefined) { 
  9.             result[key[i]] = {}; 
  10.         } 
  11.          
  12.         if(!(result[key[i]] instanceof Object)){ 
  13.             // 如果第i層對(duì)應(yīng)的不是一個(gè)對(duì)象,則剖出錯(cuò)誤 
  14.             throw new Error('is not Object'
  15.             return false 
  16.         } 
  17.          
  18.         result = result[key[i]] 
  19.     } 
  20.     return result[key[i]] = val 
  21.  
  22. // 使用 
  23. setObjAttr(obj, 'a.b.c.d''xuxi'

5.如何用迭代器的思想解決分支循環(huán)嵌套問(wèn)題

分支循環(huán)嵌套的問(wèn)題主要是指在循環(huán)體中還需要進(jìn)行額外的判斷,如果判斷條件變多,將會(huì)造成嚴(yán)重的性能開銷問(wèn)題,如下面的例子:

  1. // 數(shù)據(jù)分組 
  2. function group(name, num) { 
  3.     let data = []; 
  4.     for(let i = 0; i < num; i++){ 
  5.         switch(name) { 
  6.             case 'header'
  7.                data[i][0] = 0; 
  8.                data[i][1] = 1; 
  9.                break; 
  10.            case 'content'
  11.                data[i][0] = 2; 
  12.                data[i][1] = 3; 
  13.                break; 
  14.            case 'footer'
  15.                data[i][0] = 4; 
  16.                data[i][1] = 532; 
  17.                break; 
  18.            default
  19.                break; 
  20.         } 
  21.     } 
  22.     return data 

由以上分析可知,上面的代碼還有很多優(yōu)化空間,因?yàn)槊恳淮伪闅v都要進(jìn)行一次分支判斷,那么如果num變成100000,且name的種類有100種,那么我們就要做100000*100種無(wú)用的分支判斷,這樣無(wú)疑會(huì)讓你的代碼在大數(shù)據(jù)下卡死。不過(guò)我們可以通過(guò)以下這種方式優(yōu)化它:

  1. // 數(shù)據(jù)分組 
  2. function group(name, num) { 
  3.     let data = []; 
  4.     let strategy = function() { 
  5.         let deal = { 
  6.             'default'function(i){ 
  7.                 return 
  8.             }, 
  9.             'header'function(i){ 
  10.                data[i][0] = 0; 
  11.                data[i][1] = 1; 
  12.             }, 
  13.            'content'function(i){ 
  14.                data[i][0] = 2; 
  15.                data[i][1] = 3; 
  16.             },  
  17.             //... 
  18.         } 
  19.         return function(name) { 
  20.             return deal[name] || deal['default'
  21.         } 
  22.     }(); 
  23.     // 迭代器處理數(shù)據(jù) 
  24.     function _each(fn) { 
  25.        for(let i = 0; i < num; i++){ 
  26.         fn(i) 
  27.        } 
  28.     } 
  29.      
  30.     _each(strategy(name)) 
  31.      
  32.     return data 

這樣我們就能避免分支判斷,極大的提高了代碼效率和性能。

6.實(shí)現(xiàn)一個(gè)圖片播放器


圖片播放器主要有以上幾個(gè)功能,上一頁(yè),下一頁(yè),首頁(yè),尾頁(yè),自動(dòng)播放按鈕,停止按鈕。具體組件的設(shè)計(jì)機(jī)構(gòu)可以參考我寫的demo:

  1. // 圖片播放器 
  2. let imgPlayer = function(imgData, box) { 
  3.     let container = box && document.querySelector(box) || document, 
  4.     img = container.querySelector('img'), 
  5.     // 獲取圖片長(zhǎng)度 
  6.     len = imgData.length, 
  7.     // 當(dāng)前索引值 
  8.     index = 0; 
  9.     // 初始化圖片 
  10.     img.src = imgData[0]; 
  11.  
  12.     var timer = null
  13.  
  14.     return { 
  15.         // 獲取第一個(gè)圖片 
  16.         firstfunction() { 
  17.             index = 0 
  18.             img.src = imgData[index
  19.         }, 
  20.         // 獲取最后一個(gè)圖片 
  21.         lastfunction() { 
  22.             index = len - 1 
  23.             img.src = imgData[index
  24.         }, 
  25.         // 切換到前一張圖片 
  26.         pre: function() { 
  27.             if(--index > 0) { 
  28.                 img.src = imgData[index
  29.             }else { 
  30.                 index = 0 
  31.                 img.src = imgData[index
  32.             } 
  33.         }, 
  34.         // 切換到后一張圖片 
  35.         nextfunction() { 
  36.             if(++index < len) { 
  37.                 img.src = imgData[index
  38.             }else { 
  39.                 index = len - 1 
  40.                 img.src = imgData[index
  41.             } 
  42.         }, 
  43.         // 自動(dòng)播放圖片 
  44.         play: function() { 
  45.             timer = setInterval(() => { 
  46.                 if(index > len - 1) { 
  47.                     index = 0 
  48.                 } 
  49.                 img.src = imgData[index
  50.                 index++ 
  51.             }, 5000) 
  52.         }, 
  53.         // 停止播放圖片 
  54.         stop: function() { 
  55.             clearInterval(timer) 
  56.         } 
  57.     } 
  58.  
  59. // 使用 
  60. let player = new imgPlayer(imgData, '#box'

 總之,迭代器思想和其他設(shè)計(jì)模式的組合,可以設(shè)計(jì)出各種各樣高度配置的組件,所以說(shuō)學(xué)好并理解 javascript 設(shè)計(jì)模式的精髓,決定了我們的高度和態(tài)度。

 

責(zé)任編輯:姜華 來(lái)源: 趣談前端
相關(guān)推薦

2022-09-14 08:16:48

裝飾器模式對(duì)象

2021-09-15 10:03:30

騰訊QQ圓夢(mèng)表情

2022-04-05 13:56:48

設(shè)計(jì)模式javascript

2020-11-09 09:10:31

javascript設(shè)

2021-06-22 15:27:13

設(shè)計(jì)模式迭代器模式Java

2022-05-17 15:45:41

禮物驚喜送達(dá)線上送禮

2022-07-22 11:22:10

B 端菜鳥數(shù)字化

2010-04-29 08:53:11

PHP迭代器模式

2020-11-06 09:01:46

迭代器模式

2009-08-11 13:59:41

迭代器模式C# Iterator

2009-08-26 16:26:37

C#迭代器模式

2011-12-01 14:06:32

2018-12-04 15:08:11

QQ視覺(jué)設(shè)計(jì)APP

2018-05-23 14:58:38

云計(jì)算

2023-12-01 08:09:08

2023-11-07 10:10:36

設(shè)計(jì)模式元素

2017-12-14 14:17:08

Windows使用技巧手冊(cè)

2019-07-11 12:36:01

AR設(shè)計(jì)圖像檢測(cè)法

2023-10-20 08:04:34

系統(tǒng)重構(gòu)實(shí)踐

2023-02-27 07:40:00

系統(tǒng)重構(gòu)前端
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)