摘要:用法與參數(shù)要理解這段代碼,先來看一下的用法和參數(shù)用法參數(shù)回調(diào)函數(shù),有如下參數(shù)上一個回調(diào)函數(shù)返回的值或者是初始值當前值當前值在數(shù)組中的索引調(diào)用的數(shù)組初始值,如果沒有提供,則為數(shù)組的第一項。接下來,檢測回調(diào)函數(shù)是否為,如果不是,拋出類型錯誤。
IOS3 模塊是針對 IOS 的兼容模塊,實現(xiàn)了兩個常用方法的兼容,這兩個方法分別是 trim 和 reduce 。
讀 Zepto 源碼系列文章已經(jīng)放到了github上,歡迎star: reading-zepto
源碼版本本文閱讀的源碼為 zepto1.2.0
GitBook《reading-zepto》
trimif (String.prototype.trim === undefined) // fix for iOS 3.2 String.prototype.trim = function(){ return this.replace(/^s+|s+$/g, "") }
看注釋, trim 是為了兼容 ios3.2 的。
也是常規(guī)的做法,如果 String 的 prototype 上沒有 trim 方法,則自己實現(xiàn)一個。
實現(xiàn)的方式也簡單,就是用正則將開頭和結尾的空格去掉。^s+ 這段是匹配開頭的空格,s+$ 是匹配結尾的空格。
reduce// For iOS 3.x // from https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/reduce if (Array.prototype.reduce === undefined) Array.prototype.reduce = function(fun){ if(this === void 0 || this === null) throw new TypeError() var t = Object(this), len = t.length >>> 0, k = 0, accumulator if(typeof fun != "function") throw new TypeError() if(len == 0 && arguments.length == 1) throw new TypeError() if(arguments.length >= 2) accumulator = arguments[1] else do{ if(k in t){ accumulator = t[k++] break } if(++k >= len) throw new TypeError() } while (true) while (k < len){ if(k in t) accumulator = fun.call(undefined, accumulator, t[k], k, t) k++ } return accumulator }用法與參數(shù)
要理解這段代碼,先來看一下 reduce 的用法和參數(shù):
用法:
arr.reduce(callback[, initialValue])
參數(shù):
callback: 回調(diào)函數(shù),有如下參數(shù)
accumulator: 上一個回調(diào)函數(shù)返回的值或者是初始值(initialValue)
currentValue: 當前值
currentIndex: 當前值在數(shù)組中的索引
array: 調(diào)用 reduce 的數(shù)組
initialValue: 初始值,如果沒有提供,則為數(shù)組的第一項。如果數(shù)組為空數(shù)組,而又沒有提供初始值時,會報錯
檢測參數(shù)if(this === void 0 || this === null) throw new TypeError() var t = Object(this), len = t.length >>> 0, k = 0, accumulator if(typeof fun != "function") throw new TypeError() if(len == 0 && arguments.length == 1) throw new TypeError()
首先檢測是否為 undefined 或者 null ,如果是,則報類型錯誤。這里有一點值得注意的,判斷是否為 undefined 時,用了 void 0 的返回值,因為 void 操作符返回的結果都為 undefined ,這是為了避免 undefined 被重新賦值,出現(xiàn)誤判的情況。
接下來,將數(shù)組轉換成對象,用變量 t 來保存,后面會看到,遍歷用的是 for...in 來處理。為什么不直接用 for 來處理數(shù)組呢?因為 reduce 不會處理稀疏數(shù)組,所以轉換要轉換成對象來處理。
數(shù)組長度用 len 來保存,這里使用了無符號位右移操作符 >>> ,確保 len 為非負整數(shù)。
用 k 來保存當前索引,accumulator 為返回值。
接下來,檢測回調(diào)函數(shù) fun 是否為 function ,如果不是,拋出類型錯誤。
在數(shù)組為空,并且又沒有提供初始值(即只有一個參數(shù) fun)時,拋出類型錯誤。
accumulator初始值if(arguments.length >= 2) accumulator = arguments[1] else do{ if(k in t){ accumulator = t[k++] break } if(++k >= len) throw new TypeError() } while (true)
如果參數(shù)至少有兩項,則 accumulator 的初始值很簡單,就是 arguments[1] ,即 initialValue。
如果沒有提供初始值,則迭代索引,直到找到在對象 t 中存在的索引。注意這里用了 do...while,所以最終結果,要么是報類型錯誤,要么 accumulator 能獲取到值。
這段還巧妙地用了 ++k 和 k++ 。如果 k 在對象 t 中存在時,則賦值給 accumulator 后 k 再自增,否則用 k 自增后再和 len 比較,如果超出 len 的長度,則報錯,因為不存在下一個可以賦給 accumulator 的值。
返回結果while (k < len){ if(k in t) accumulator = fun.call(undefined, accumulator, t[k], k, t) k++ } return accumulator
要注意,如果沒有提供初始值時,k 是自增后的值,即不再需要處理數(shù)組的第一個值。
到這里問題就比較簡單了,就是 while 循環(huán),用 accumulator 保存回調(diào)函數(shù)返回的值,在下一次循環(huán)時,再將 accumulator 作為參數(shù)傳遞給回調(diào)函數(shù),直至數(shù)組耗盡,然后將結果返回。
系列文章《reading-zepto》
系列文章讀Zepto源碼之代碼結構
讀Zepto源碼之內(nèi)部方法
讀Zepto源碼之工具函數(shù)
讀Zepto源碼之神奇的$
讀Zepto源碼之集合操作
讀Zepto源碼之集合元素查找
讀Zepto源碼之操作DOM
讀Zepto源碼之樣式操作
讀Zepto源碼之屬性操作
讀Zepto源碼之Event模塊
讀Zepto源碼之IE模塊
讀Zepto源碼之Callbacks模塊
讀Zepto源碼之Deferred模塊
讀Zepto源碼之Ajax模塊
讀Zepto源碼之Assets模塊
讀Zepto源碼之Selector模塊
讀Zepto源碼之Touch模塊
讀Zepto源碼之Gesture模塊
附文譯:怎樣處理 Safari 移動端對圖片資源的限制
參考Array.prototype.reduce()
License署名-非商業(yè)性使用-禁止演繹 4.0 國際 (CC BY-NC-ND 4.0)
最后,所有文章都會同步發(fā)送到微信公眾號上,歡迎關注,歡迎提意見:
作者:對角另一面
文章版權歸作者所有,未經(jīng)允許請勿轉載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/88817.html
摘要:讀源碼系列文章已經(jīng)放到了上,歡迎源碼版本本文閱讀的源碼為改寫原有的方法模塊改寫了以上這些方法,這些方法在調(diào)用的時候,會為返回的結果添加的屬性,用來保存原來的集合。方法的分析可以看讀源碼之模塊。 Stack 模塊為 Zepto 添加了 addSelf 和 end 方法。 讀 Zepto 源碼系列文章已經(jīng)放到了github上,歡迎star: reading-zepto 源碼版本 本文閱讀的...
摘要:模塊處理的是表單提交。表單提交包含兩部分,一部分是格式化表單數(shù)據(jù),另一部分是觸發(fā)事件,提交表單。最終返回的結果是一個數(shù)組,每個數(shù)組項為包含和屬性的對象。否則手動綁定事件,如果沒有阻止瀏覽器的默認事件,則在第一個表單上觸發(fā),提交表單。 Form 模塊處理的是表單提交。表單提交包含兩部分,一部分是格式化表單數(shù)據(jù),另一部分是觸發(fā) submit 事件,提交表單。 讀 Zepto 源碼系列文章已...
摘要:所以模塊依賴于模塊,在引入前必須引入模塊。原有的方法分析見讀源碼之樣式操作方法首先調(diào)用原有的方法,將元素顯示出來,這是實現(xiàn)動畫的基本條件。如果沒有傳遞,或者為值,則表示不需要動畫,調(diào)用原有的方法即可。 fx 模塊提供了 animate 動畫方法,fx_methods 利用 animate 方法,提供一些常用的動畫方法。所以 fx_methods 模塊依賴于 fx 模塊,在引入 fx_m...
摘要:的模塊用來獲取節(jié)點中的屬性的數(shù)據(jù),和儲存跟相關的數(shù)據(jù)。獲取節(jié)點指定的緩存值。如果存在,則刪除指定的數(shù)據(jù),否則將緩存的數(shù)據(jù)全部刪除。為所有下級節(jié)點,如果為方法,則節(jié)點自身也是要被移除的,所以需要將自身也加入到節(jié)點中。 Zepto 的 Data 模塊用來獲取 DOM 節(jié)點中的 data-* 屬性的數(shù)據(jù),和儲存跟 DOM 相關的數(shù)據(jù)。 讀 Zepto 源碼系列文章已經(jīng)放到了github上,歡...
摘要:模塊基于上的事件的封裝,利用屬性,封裝出系列事件。這個判斷需要引入設備偵測模塊。然后是監(jiān)測事件,根據(jù)這三個事件,可以組合出和事件。其中變量對象和模塊中的對象的作用差不多,可以先看看讀源碼之模塊對模塊的分析。 Gesture 模塊基于 IOS 上的 Gesture 事件的封裝,利用 scale 屬性,封裝出 pinch 系列事件。 讀 Zepto 源碼系列文章已經(jīng)放到了github上,歡...
閱讀 1384·2021-09-24 10:26
閱讀 1695·2019-08-30 14:14
閱讀 2105·2019-08-29 16:54
閱讀 367·2019-08-29 14:09
閱讀 1477·2019-08-29 12:55
閱讀 930·2019-08-28 18:13
閱讀 1582·2019-08-26 13:39
閱讀 2566·2019-08-26 11:43