摘要:遍歷中的所有元素,按順序用遍歷輸出每個元素。如果傳遞了參數,則把綁定到對象上。返回以方便鏈式調用。
each _.each(list, iteratee, [context])?Alias:?forEach?
遍歷list中的所有元素,按順序用遍歷輸出每個元素。如果傳遞了context參數,則把iteratee綁定到context對象上。每次調用iteratee都會傳遞三個參數:(element, index, list)。如果list是個JavaScript對象,iteratee的參數是?(value, key, list))。返回list以方便鏈式調用。
_.each([1, 2, 3], alert); => alerts each number in turn... _.each({one: 1, two: 2, three: 3}, alert); => alerts each number value in turn...
_.each 源碼
// The cornerstone, an `each` implementation, aka `forEach`. // Handles raw objects in addition to array-likes. Treats all // sparse array-likes as if they were dense. _.each = _.forEach = function(obj, iteratee, context) { iteratee = optimizeCb(iteratee, context); var i, length; if (isArrayLike(obj)) { for (i = 0, length = obj.length; i < length; i++) { iteratee(obj[i], i, obj); } } else { var keys = _.keys(obj); for (i = 0, length = keys.length; i < length; i++) { iteratee(obj[keys[i]], keys[i], obj); } } return obj; };
分析
_.each([1, 2, 3], alert); // _.each()使用方法,其中`alert`可以換成自己寫的function
obj 是[1, 2, 3] , iteratee 是alert , context 沒有
iteratee = optimizeCb(iteratee, context);
首先是調用optimizeCb()函數
分析 optimizeCb 源碼
var optimizeCb = function(func, context, argCount) { if (context === void 0) return func; };
因為context 沒有,所以這里直接返回alert , 所以 iteratee 現在是alert
再使用 isArrayLike 判斷 傳進來的obj是不是數組,判斷數組的方法
//原理就是通過判斷它是否具有長度且長度大于0且小于MAX_ARRAY_INDEX var MAX_ARRAY_INDEX = Math.pow(2, 53) - 1; var getLength = property("length"); var isArrayLike = function(collection) { var length = getLength(collection); return typeof length == "number" && length >= 0 && length <= MAX_ARRAY_INDEX; };
因為這里是數組,所以繼續
// 通過 for 循環來遍歷數組里面每一個值,傳給 iteratee 函數來運行 for (i = 0, length = obj.length; i < length; i++) { iteratee(obj[i], i, obj); // 等于 alert(obj[i], i, obj); }
如果不是數組呢?對象默認是沒有length 屬性的
var keys = _.keys(obj); for (i = 0, length = keys.length; i < length; i++) { iteratee(obj[keys[i]], keys[i], obj); }
使用了_.keys() 函數,下面分析 _keys() 源碼
_.keys = function(obj) { if (!_.isObject(obj)) return []; if (nativeKeys) return nativeKeys(obj); var keys = []; for (var key in obj) if (_.has(obj, key)) keys.push(key); // Ahem, IE < 9. if (hasEnumBug) collectNonEnumProps(obj, keys); return keys; };
首先使用_.isObject函數判斷是不是對象
// Is a given variable an object? _.isObject = function(obj) { var type = typeof obj; return type === "function" || type === "object" && !!obj; };
首先判斷傳進來的參數的類型,然后返回true或者false
注意,通過以下兩個例子可知, && 的優先級比 || 的高
console.log(true || false && false) // true console.log(true || false && true) // true
然后如果瀏覽器支持 ES5 的 Object.keys 方法,就優先使用
nativeKeys = Object.keys,
不支持就繼續遍歷循環 對象
var keys = []; // own enumerable properties for (var key in obj) // hasOwnProperty if (_.has(obj, key)) keys.push(key);
使用了 _.has() 函數,下面解析_.has()函數
// Shortcut function for checking if an object has a given property directly // on itself (in other words, not on a prototype). _.has = function(obj, key) { return obj != null && hasOwnProperty.call(obj, key); };
通過判斷 傳進來的obj 是否為null 并且調用hasOwnProperty 方法判斷該對象是否有該鍵值
hasOwnProperty = ObjProto.hasOwnProperty = Object.prototype.hasOwnProperty;
如果有該屬性,返回true ,這時回到_.keys() ,該簡直push 到keys[] 內
// IE9以下不能用 for in 來遍歷,所以使用collectNonEnumProps()函數來解決問題,暫時可以不看 if (hasEnumBug) collectNonEnumProps(obj, keys);
這時已經把對象轉化成數組了,回到_.each() 函數,繼續使用for 循環遍歷數組 ,把參數傳遞給alert函數
for (i = 0, length = keys.length; i < length; i++) { iteratee(obj[keys[i]], keys[i], obj); // 等于 alert(obj[keys[i]], keys[i], obj); }
最后再返回obj
整個分析_.each() 函數,相繼分析了_.has() 和_.keys() 函數,大概看了一下underscore.js 的源碼,感覺不是太難,一個函數一個函數分析就好。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/80826.html
摘要:譯立即執行函數表達式處理支持瀏覽器環境微信小程序。學習整體架構,利于打造屬于自己的函數式編程類庫。下一篇文章可能是學習的源碼整體架構。也可以加微信,注明來源,拉您進前端視野交流群。 前言 上一篇文章寫了jQuery整體架構,學習 jQuery 源碼整體架構,打造屬于自己的 js 類庫 雖然看過挺多underscore.js分析類的文章,但總感覺少點什么。這也許就是紙上得來終覺淺,絕知此...
摘要:所以,剛開始,我從源碼比較短的包含注釋只有行開始學習起。一般,在客戶端瀏覽器環境中,即為,暴露在全局中。學習以后判斷直接使用看起來也優雅一點滑稽臉。在的函數視線中,的作用執行一個傳入函數次,并返回由每次執行結果組成的數組。 前言 最近在社區瀏覽文章的時候,看到了一位大四學長在尋求前端工作中的面經,看完不得不佩服,掌握知識點真是全面,無論是前端后臺還是其他,都有涉獵。 在他寫的文章中,有...
摘要:前面的的目的在于利用自定義拋出錯誤令遍歷停止如果是數組直接過濾輸出不是數組遍歷操作壓入數組返回有點像,過濾符合條件的注意感嘆號取反有點像設置默認迭代器判斷是否存在即需要所有元素都滿足迭代條件。 前言 這篇文章是為之后的underscore現版本的源碼做鋪墊,先感受下最先版本 0.1.0版本足夠小 這個版本已經有將近小10年的歷史了 還是有一些不錯的地方。 0.1.0版本源碼分析 ...
摘要:最近開始看源碼,并將源碼解讀放在了我的計劃中。今天就跟大家聊一聊中一些常用類型檢查方法,以及一些工具類的判斷方法。用是否含有屬性來判斷工具類判斷方法接下來看下一些常用的工具類判斷方法。 Why underscore 最近開始看 underscore.js 源碼,并將 underscore.js 源碼解讀 放在了我的 2016 計劃中。 閱讀一些著名框架類庫的源碼,就好像和一個個大師對話...
摘要:創建一個全局對象在瀏覽器中表示為對象在中表示對象保存下劃線變量被覆蓋之前的值如果出現命名沖突或考慮到規范可通過方法恢復被占用之前的值并返回對象以便重新命名創建一個空的對象常量便于內部共享使用將內置對象的原型鏈緩存在局部變量方便快速調用將 // Underscore.js 1.3.3 // (c) 2009-2012 Jeremy Ashkenas, DocumentCloud Inc....
閱讀 1176·2021-10-11 10:59
閱讀 1963·2021-09-29 09:44
閱讀 853·2021-09-01 10:32
閱讀 1424·2019-08-30 14:21
閱讀 1870·2019-08-29 15:39
閱讀 2973·2019-08-29 13:45
閱讀 3532·2019-08-29 13:27
閱讀 2006·2019-08-29 12:27