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