摘要:前面的的目的在于利用自定義拋出錯誤令遍歷停止如果是數組直接過濾輸出不是數組遍歷操作壓入數組返回有點像,過濾符合條件的注意感嘆號取反有點像設置默認迭代器判斷是否存在即需要所有元素都滿足迭代條件。
前言
這篇文章是為之后的underscore現版本的源碼做鋪墊,先感受下最先版本
0.1.0版本足夠小
這個版本已經有將近小10年的歷史了
還是有一些不錯的地方。
0.1.0版本源碼分析
// Underscore.js // (c) 2009 Jeremy Ashkenas, DocumentCloud Inc. // Underscore is freely distributable under the terms of the MIT license. // Portions of Underscore are inspired by or borrowed from Prototype.js, // Oliver Steele"s Functional, And John Resig"s Micro-Templating. // For all details and documentation: // http://documentcloud.github.com/underscore/ window._ = { VERSION : "0.1.0", /*------------------------ Collection Functions: ---------------------------*/ // 集合函數 // The cornerstone, an each implementation. // Handles objects implementing forEach, each, arrays, and raw objects. each : function(obj, iterator, context) { var index = 0; try { if (obj.forEach) { // 有forEach優先選擇forEach obj.forEach(iterator, context); } else if (obj.length) { // 使用自定義迭代器迭代 for (var i=0; i總結= result.computed) result = {value : value, computed : computed}; // 對初始化以及每一次判斷computed大于當前值更新 }); return result.value; }, // Return the minimum element (or element-based computation). min : function(obj, iterator, context) { if (!iterator && _.isArray(obj)) return Math.min.apply(Math, obj); var result; _.each(obj, function(value, index) { var computed = iterator ? iterator.call(context, value, index) : value; if (result == null || computed < result.computed) result = {value : value, computed : computed}; }); return result.value; }, // Sort the object"s values by a criteria produced by an iterator. sortBy : function(obj, iterator, context) { // 根據對象的一些值進行排序 // 首先我們只要關注每個函數的目的即可 // map一次遍歷,返回多個對象數組。然后根據數組對象排序 // 并且對象均有值為criteria表示我們迭代函數的值(就是根據什么排序) return _.pluck(_.map(obj, function(value, index) { return { value : value, criteria : iterator.call(context, value, index) }; }).sort(function(left, right) { var a = left.criteria, b = right.criteria; // 判斷大于小于等于 return a < b ? -1 : a > b ? 1 : 0; }), "value"); // 外面的一層pluck是為了解開map函數的一層打包 }, // Use a comparator function to figure out at what index an object should // be inserted so as to maintain order. Uses binary search. // 這是利用二分查找吧 // 利用二分查找找出元素應該插入到哪個位置中 sortedIndex : function(array, obj, iterator) { iterator = iterator || function(val) { return val; }; // 初始化一個迭代器 var low = 0, high = array.length;//不嚴謹直接去length // 初始化高低位 // while (low < high) { var mid = (low + high) >> 1; // 對中位取半(important快捷方法) iterator(array[mid]) < iterator(obj) ? low = mid + 1 : high = mid; } return low; }, // Convert anything iterable into a real, live array. // 轉換數組(轉換一切可迭代的) toArray : function(iterable) { if (!iterable) return []; //為假值直接返回[] if (_.isArray(iterable)) return iterable; //判斷是否為數組 return _.map(iterable, function(val){ return val; });//如果為對象的話,利用map轉成數組 }, // Return the number of elements in an object. // 返回對象的元素數量 size : function(obj) { return _.toArray(obj).length; }, /*-------------------------- Array Functions: ------------------------------*/ // Get the first element of an array. // 返回數組第一個元素 first : function(array) { return array[0]; }, // Get the last element of an array. // 返回數組最后一個元素 last : function(array) { return array[array.length - 1]; }, // Trim out all falsy values from an array. //去除假值的數組元素 //需要傳入一個操作函數 false值在兩次取反會被去掉 compact : function(array) { return _.select(array, function(value){ return !!value; }); }, // Return a completely flattened version of an array. //多維數組返回一個一維數組 // 數組扁平化 // 開始展現出函數式編程的靈活性了 flatten : function(array) { return _.inject(array, [], function(memo, value) { // 這邊如果還是數組的話進行一個遞歸的扁平 if (_.isArray(value)) return memo.concat(_.flatten(value)); memo.push(value); return memo; }); }, // Return a version of the array that does not contain the specified value(s). // 對傳入的數組進行篩選 // 這里有一個點,我們在傳參形參定義了array // 而在下面的地方我們可以直接使用array且slice截取arguments without : function(array) { var values = array.slice.call(arguments, 0); return _.select(array, function(value){ return !_.include(values, value); }); }, // Produce a duplicate-free version of the array. If the array has already // been sorted, you have the option of using a faster algorithm. // 唯一的數組。有一個參數可以選擇是否排序的數組,是的話會選擇最快的算法 uniq : function(array, isSorted) { return _.inject(array, [], function(memo, el, i) { if (0 == i || (isSorted ? _.last(memo) != el : !_.include(memo, el))) memo.push(el); return memo; }); }, // Produce an array that contains every item shared between all the // passed-in arrays. // 篩選多個元素數組的相同值 intersect : function(array) { var rest = _.toArray(arguments).slice(1); // 獲得其余多個參數 // 最外面肯定是一層篩選。 // 里面做篩選的條件 return _.select(_.uniq(array), function(item) { return _.all(rest, function(other) { // 目的在于取交集 // 所以我們使用外層的item 對比層的個個數組 據此我們返回同時存在多個數組中的元素 return _.indexOf(other, item) >= 0; }); }); }, // Zip together multiple lists into a single array -- elements that share // an index go together. zip : function() { var args = _.toArray(arguments); var length = _.max(_.pluck(args, "length")); // 返回最大數組的長度。 var results = new Array(length); // 創建一個存放點 for (var i=0; i 提取替換 var fn = new Function("obj", "var p=[],print=function(){p.push.apply(p,arguments);};" + "with(obj){p.push("" + str .replace(/[ ]/g, " ") .split("<%").join(" ") .replace(/((^|%>)[^ ]*)"/g, "$1 ") .replace(/ =(.*?)%>/g, "",$1,"") .split(" ").join("");") .split("%>").join("p.push("") .split(" ").join(""") + "");}return p.join("");"); return data ? fn(data) : fn; } };
后面的模板實現挺亮眼。
try catch 設計each的跳出。
>> 取半的快捷
函數的復用。(有部分也許是不高效)
整個版本時間很前。所以我們可以從中看到一些現代api的影子,也許是在現代api中看到它們的影子。
源碼篇幅較少,加上注釋也不過400行左右。整篇閱讀下來也沒有很大的障礙,就是有復用性相對較高,但是對著test文件看看測試用例也就好了~~~
可以通過這些地方聯系我我的博客
我的郵箱:kang95630@gmail.com
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/93320.html
摘要:最近開始看源碼,并將源碼解讀放在了我的計劃中。相對于其他源碼解讀的文章,基本都會從整體設計開始講起,樓主覺得這個庫有點特殊,決定按照自己的思路,從用代替說起。源碼沒有出現注意,其實有出現一處,是為,而不是,而用代替之。 Why underscore 最近開始看 underscore源碼,并將 underscore源碼解讀 放在了我的 2016計劃 中。 閱讀一些著名框架類庫的源碼,就好...
摘要:所以它與其他系列的文章并不沖突,完全可以在閱讀完這個系列后,再跟著其他系列的文章接著學習。如何閱讀我在寫系列的時候,被問的最多的問題就是該怎么閱讀源碼我想簡單聊一下自己的思路。感謝大家的閱讀和支持,我是冴羽,下個系列再見啦 前言 別名:《underscore 系列 8 篇正式完結!》 介紹 underscore 系列是我寫的第三個系列,前兩個系列分別是 JavaScript 深入系列、...
摘要:開始研究核心代碼這個類首先是構造函數看完上面的內容大家應該有點印象,上掛了和,是默認的配置,顧名思義就是攔截器,目測包含了和兩種類型。喜歡就點個贊吧參考文章源代碼重點難點分析源代碼重點難點分析 axios是一個基于promise的http庫,支持瀏覽器和node端,最近我在做beauty-we的api設計,研讀一個成熟的http庫勢在必行,axios功能完整、api簡潔、注釋清晰,再適...
摘要:此次源碼分析為以前曾讀過一次,可是沒有做下筆記。類似的兼容寫法記錄版本號優化回調特指函數中傳入的回調是一個真正的因為是可以被賦值的防止值被篡改接下來就是保證回調函數的執行上下文。 此次源碼分析為 1.8.3 version 以前曾讀過一次,可是沒有做下筆記。此次重新閱讀特制此筆記 Baseline setup underscore是包裹在一個閉包內部的防止污染全局變量 (functio...
閱讀 1914·2021-09-23 11:21
閱讀 1701·2019-08-29 17:27
閱讀 1059·2019-08-29 17:03
閱讀 728·2019-08-29 15:07
閱讀 1922·2019-08-29 11:13
閱讀 2381·2019-08-26 12:14
閱讀 922·2019-08-26 11:52
閱讀 1733·2019-08-23 17:09