迭代器是一個框架的重要設計。我們經常需要提供一種方法順序用來處理聚合對象中各個元素,而又不暴露該對象的內部,這也是設計模式中的迭代器模式(Iterator)。
jQuery中的$.each方法就是一個典型的迭代器,通過each我們可以傳入額外的function,然后來對所有的item項進行迭代操作,如下代碼:
$.each([52, 97], function(index, value) { alert(index + ': ' + value); }); $( "li" ).each(function( index ) { console.log( index + ": "" + $(this).text() ); });
針對迭代器,這里有幾個特點:
? 訪問一個聚合對象的內容而無需暴露它的內部。
? 為遍歷不同的集合結構提供一個統一的接口,從而支持同樣的算法在不同的集合結構上進行操作。
? 遍歷的同時更改迭代器所在的集合結構可能會導致問題。
簡單的說:封裝實現,然后迭代器的聚合對象不用關心迭代的過程,從而符合SRP原則。
拋開jQuery的each方法,我們自己實現一個有簡單的迭代器功能的代碼:
1、簡單回調
function each(obj, callback) { var i = 0; var value; var length = obj.length; for (; i < length; i++) { callback(obj[i]); } } var arr = ['a', 'b', 'c']; each(arr, function(name) { console.log(name); })
這樣就滿足了迭代模式的設計原則,對于集合內部結果常常變化各異,我們不想暴露其內部結構,但又想讓客戶代碼透明地訪問其中的元素,通過回調把邏輯給解耦出來。但是這樣的處理其實太簡單了,我們還要考慮至少四種情況:
? 聚合對象,可能是對象,字符串或者數組等類型
? 支持參數傳遞
? 支持上下文的傳遞
? 支持循環中退出
我們簡單的修改一下上面的代碼:
function each(obj, callback, context, arg) { var i = 0; var value; var length = obj.length; for (; i < length; i++) { callback.call(context || null, obj[i], arg); } } var arr = ['a', 'b', 'c']; each(arr, function(name, arg) { console.log(name, arg ,this); }, this, 'aaa')
當然根據回調的處理,從而判斷是否要立刻中斷這個循環,從而節約性能,也是很簡單的,我們可以通過獲取處理的返回值來處理,如下代碼:
function each(obj, callback, context, arg) { var i = 0; var value; var length = obj.length; for (; i < length; i++) { value = callback.call(context || null, obj[i], arg); if (value === false) { break; } }
可見只要通過回調函數callback返回的ture/false的布爾值結果就可以來判斷當前是否要強制退出循環。
請驗證,完成請求
由于請求次數過多,請先驗證,完成再次請求
打開微信掃碼自動綁定
綁定后可得到
使用 Ctrl+D 可將課程添加到書簽
舉報