摘要:最近開始看源碼,并將源碼解讀放在了我的計劃中。將轉為數組同時去掉第一個元素之后便可以調用方法總結數組的擴展方法就解讀到這里了,相關源碼可以參考這部分。放個預告,下一篇會暫緩下,講下相關的東西,敬請期待。
Why underscore
最近開始看 underscore.js 源碼,并將 underscore.js 源碼解讀 放在了我的 2016 計劃中。
閱讀一些著名框架類庫的源碼,就好像和一個個大師對話,你會學到很多。為什么是 underscore?最主要的原因是 underscore 簡短精悍(約 1.5k 行),封裝了 100 多個有用的方法,耦合度低,非常適合逐個方法閱讀,適合樓主這樣的 JavaScript 初學者。從中,你不僅可以學到用 void 0 代替 undefined 避免 undefined 被重寫等一些小技巧 ,也可以學到變量類型判斷、函數節流&函數去抖等常用的方法,還可以學到很多瀏覽器兼容的 hack,更可以學到作者的整體設計思路以及 API 設計的原理(向后兼容)。
之后樓主會寫一系列的文章跟大家分享在源碼閱讀中學習到的知識。
underscore-1.8.3 源碼解讀項目地址 https://github.com/hanzichi/underscore-analysis
underscore-1.8.3 源碼全文注釋 https://github.com/hanzichi/underscore-analysis/blob/master/underscore-1.8.3.js/underscore-1.8.3-analysis.js
underscore-1.8.3 源碼解讀系列文章 https://github.com/hanzichi/underscore-analysis/issues
歡迎圍觀~ (如果有興趣,歡迎 star & watch~)您的關注是樓主繼續寫作的動力
Main很快,Array Functions 部分到了尾聲,今天來做個了(xiao)結。
underscore 給數組(以及 arguments,這里特別說明下,underscore 的數組擴展方法,同樣適用于 arguments)增加了 20 個擴展方法,值得一提的是,很多有意思的方法,比如 map,shuffle 等,都被放在了 Collection Functions 中。本文來看看 Array Functions 中還有哪些有意思的方法(之前沒有被提及)。
_.compact這個方法很有意思,它的作用是剔除數組中的假值,返回數組副本。
實現非常的簡單:
_.compact = function(array) { return _.filter(array, _.identity); };
_.filter 我們在以后會講到,這里你可以把它理解為 Array.prototype.filter 的一個 polyfill,來看看 _.identity 是個什么東東。
_.identity = function(value) { return value; };
乍一看,_.identity 似乎沒什么卵用,傳入一個參數,原封不動返回這個參數,什么鬼?而再看 _.compact 的實現,就會發現非常巧妙!細細品味下,直接過濾了數組的假值,而 _.identity 在源碼中能在多個地方復用。
從這個方法可以想到 PHP 的 array_filter 函數。array_filter 的基本用法和 Array.prototype.filter 相似,都是為了過濾數組中的元素。
function isOdd($num) { return $num & 1; } $a = Array(1, 2, 3); $a = array_filter($a, "isOdd"); var_dump($a); // array // 0 => int 1 // 2 => int 3
但是,值得注意的是:
If no callback is supplied, all entries of array equal to FALSE (see converting to boolean) will be removed.
這就有點 6 了,直接把 _.filter 和 _.compact 兩個方法合二為一了。
$a = Array(0, 1, 2, 3, null, false, 4); $a = array_filter($a); var_dump($a); // array // 1 => int 1 // 2 => int 2 // 3 => int 3 // 6 => int 4
Array.prototype.filter 為何不設計成這樣呢?沒有 callback 傳入的時候,直接過濾假值...
_.difference & _.without先來看 _.without,它的作用是從數組中剔除指定的元素。
var a = [1, 2, 3, 4, 5]; var ans = _.without(a, 1, 2, 3); console.log(ans); // [4, 5]
恩,沒錯,剔除數組 a 中的 value 為 1, 2, 3 的元素,這個過程中用 === 來進行比較。該方法傳入的第一個參數是數組,后面的參數為單個元素。
而 _.difference 呢?和 _.without 的唯一區別是,第二個參數開始傳入的是數組。(分別和數組中的元素比較)
var a = [1, 2, 3, 4, 5]; var ans = _.difference(a, [1, 2, 3], [5, 6]); console.log(ans); // [4]
從 a 數組中剔除 1,2,3,5,6。
仔細一想,如果已經實現了 _.difference,我們把 _.without 的參數放入數組,然后傳入 _.difference 就 ok 了!倒過來就不行了(思考下為什么)。
來看 _.difference 的實現,非常簡單:
// _.difference(array, *others) _.difference = function(array) { // 將 others 數組展開一層 // rest[] 保存展開后的元素組成的數組 // strict 參數為 true // 不可以這樣用 _.difference([1, 2, 3, 4, 5], [5, 2], 10); // 10 就會取不到 var rest = flatten(arguments, true, true, 1); // 遍歷 array,過濾 return _.filter(array, function(value){ // 如果 value 存在在 rest 中,則過濾掉 return !_.contains(rest, value); }); };
不熟悉 flatten 的可以看看 前文,當 shallow 和 strict 均為 true 時,展開一層,并且過濾非數組元素,即可以起到將多個數組合并的作用。之后利用 ._filter 進行過濾即可。
而 _.without 方法則建立在 _.difference 基礎上。
_.without = function(array) { // slice.call(arguments, 1) // 將 arguments 轉為數組(同時去掉第一個元素) // 之后便可以調用 _.difference 方法 return _.difference(array, slice.call(arguments, 1)); };總結
數組的擴展方法就解讀到這里了,相關源碼可以參考 https://github.com/hanzichi/underscore-analysis/blob/master/underscore-1.8.3.js/src/underscore-1.8.3.js#L450-L693 這部分。接下去要解讀的是 Collection Functions 部分,所謂 Collection,正是 Object & Array,也就是說這部分方法既可以用于 Object 也能用于 Array,比如我們熟悉的 map,filter,shuffle 等等,都在這部分內。
放個預告,下一篇會暫緩下 Collection Functions,講下 array-like 相關的東西,敬請期待。
PS:堅持一件事真的挺難,一個月來,每天堅持看點源碼,幾乎把所有業余時間花在了上面,寫了 10 篇隨筆,每篇文章寫的時間不短,關鍵還需要構思,如何提煉出一個主題,如何寫讓人看了會有所收獲,恩,繼續堅持。請關注我的 Repo https://github.com/hanzichi/underscore-analysis 支持我~
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/79637.html
摘要:直接來看例子一目了然,第一個參數是對象,第二個參數可以是一系列的值,也可以是數組數組中含,也可以是迭代函數,我們根據值,或者迭代函數來過濾中的鍵值對,返回新的對象副本。 Why underscore 最近開始看 underscore.js 源碼,并將 underscore.js 源碼解讀 放在了我的 2016 計劃中。 閱讀一些著名框架類庫的源碼,就好像和一個個大師對話,你會學到很多。...
摘要:支持形式的調用這其實是非常經典的無構造,其實就是一個構造函數,的結果就是一個對象實例,該實例有個屬性,屬性值是。 前言 終于,樓主的「Underscore 源碼解讀系列」underscore-analysis 即將進入尾聲,關注下 timeline 會發現樓主最近加快了解讀速度。十一月,多事之秋,最近好多事情搞的樓主心力憔悴,身心俱疲,也想盡快把這個系列完結掉,也好了卻一件心事。 本文...
摘要:今天要講的是,如何在數組中尋找元素,對應中的,,,以及方法。如果往一個有序數組中插入元素,使得數組繼續保持有序,那么這個插入位置是這就是這個方法的作用,有序,很顯然用二分查找即可。 Why underscore (覺得這部分眼熟的可以直接跳到下一段了...) 最近開始看 underscore.js 源碼,并將 underscore.js 源碼解讀 放在了我的 2016 計劃中。 閱讀一...
摘要:最近開始看源碼,并將源碼解讀放在了我的計劃中。像和使用內置構造函數所創建的對象都會繼承自和的不可枚舉屬性,例如的方法或者的方法。循環將迭代對象的所有可枚舉屬性和從它的構造函數的繼承而來的包括被覆蓋的內建屬性。 Why underscore 最近開始看 underscore.js 源碼,并將 underscore.js 源碼解讀 放在了我的 2016 計劃中。 閱讀一些著名框架類庫的源碼...
摘要:看完部分的源碼,首先迫不及待想跟大家分享的正是本文主題數組亂序。這是一道經典的前端面試題,給你一個數組,將其打亂,返回新的數組,即為數組亂序,也稱為洗牌問題。關于數組亂序,正確的解法應該是,復雜度。 前言 終于可以開始 Collection Functions 部分了。 可能有的童鞋是第一次看樓主的系列文章,這里再做下簡單的介紹。樓主在閱讀 underscore.js 源碼的時候,學到...
閱讀 1207·2019-08-30 15:55
閱讀 954·2019-08-30 15:55
閱讀 2149·2019-08-30 15:44
閱讀 2879·2019-08-29 14:17
閱讀 1129·2019-08-29 12:45
閱讀 3301·2019-08-26 10:48
閱讀 3132·2019-08-23 18:18
閱讀 2599·2019-08-23 16:47