国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > JavaScript > 正文

Underscore源碼分析

2019-11-20 10:53:44
字體:
來源:轉載
供稿:網友

幾年前就有人說javascript是最被低估一種編程語言,自從nodejs出來后,全端(All Stack/Full Stack)概念日漸興起,現在恐怕沒人再敢低估它了。javascrip是一種類C的語言,有C語言基礎就能大體理解javascript的代碼,但是作為一種腳本語言,javascript的靈活性是C所遠遠不及的,這也會造成學習上的一些困難。

一、集合

 1.首先是幾個迭代的方法。

_.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; }; 

ES為數組同樣添加了原生的forEach()方法。不同的是這里的each(forEach)方法可以對所有集合使用,函數接受三個參數(集合、迭代函數、執行環境)。

optimizeCb函數根據迭代函數參數個數的不同為不同的迭代方法綁定了相應的執行環境,forEach迭代函數同樣接受三個參數(值,索引,集合)。

接下來就是for循環調用迭代函數了。 

_.map中一種更優雅的判斷isArrayLike的實現方式:(只用一個for循環)

var keys = !isArrayLike(obj) && _.keys(obj),    length = (keys || obj).length,    results = Array(length);  for (var index = 0; index < length; index++) {   var currentKey = keys ? keys[index] : index;   results[index] = iteratee(obj[currentKey], currentKey, obj);  }  return results;  // 合理使用&&、||、?:可以大大減少代碼量 

還有兩個特別的地方:

•將集合分成了類數組集合和對象集合。使用了isArrayLike函數:

// js的最大精確整數 var MAX_ARRAY_INDEX = Math.pow(2, 53) - 1; var isArrayLike = function(collection) {var length = collection != null && collection.length;return typeof length == 'number' && length >= 0 && length <= MAX_ARRAY_INDEX; }; // 如果集合有Length屬性且為數字并且大于0小于最大的精確整數,則判定是類數組

 •使用了_.keys函數,Object同樣有原生的keys函數,用于返回一個集合obj可被枚舉的屬性數組。實現比較簡單,for in加上hasOwnProperty()方法。

--------------------------------------------------------------------------------

_.map,_.reduce方法原理類似.

 _.find函數和Array.some()類似,不同的是返回的是第一個使迭代結果為真的那個元素,而不是Array.some()那樣返回布爾值。

 _.find = _.detect = function(obj, predicate, context) {  var key;  if (isArrayLike(obj)) {   key = _.findIndex(obj, predicate, context);  } else {   key = _.findKey(obj, predicate, context);  }  if (key !== void 0 && key !== -1) return obj[key]; };function createIndexFinder(dir) {  return function(array, predicate, context) {   predicate = cb(predicate, context);   var length = array != null && array.length;   // 如果dir為1,index為0,index+=1,index正序循環   // 如果dir 為-1,index為length-1,index += -1反序循環   // 判斷循環條件則用了index >= 0 && index < length方法兼顧兩種循環方式   var index = dir > 0 ? 0 : length - 1;   for (; index >= 0 && index < length; index += dir) {    if (predicate(array[index], index, array)) return index;   }   return -1;  }; } _.findIndex = createIndexFinder(1); _.findLastIndex = createIndexFinder(-1); 

值得借鑒的地方是這里的一個for循環能夠根據傳入的參數不同配置不同的循環順序。

 1.集合中的其他方法基本都是基于迭代方法來實現的。

_.max = function(obj, iteratee, context) {var result = -Infinity, lastComputed = -Infinity,  value, computed;if (iteratee == null && obj != null) { obj = isArrayLike(obj) ? obj : _.values(obj); for (var i = 0, length = obj.length; i < length; i++) {  value = obj[i];  if (value > result) {   result = value;  } }} else { iteratee = cb(iteratee, context); _.each(obj, function(value, index, list) {  computed = iteratee(value, index, list);  if (computed > lastComputed || computed === -Infinity && result === -Infinity) {   result = value;   lastComputed = computed;  } });}return result; }; 

  max方法用于尋找集合中的最大值,通過循環list中的所有項,然后比較當前項和結果項,如果當前項大于結果,則將其賦給結果項,最后返回結果項。

 2.集合轉換為數組

 _.toArray = function(obj) {    if (!obj) return [];    // 如果是數組,采用了Array.prototype.slice.call(this,obj)這種方法    if (_.isArray(obj)) return slice.call(obj);    // 類數組對象,這里沒有采用Slice方法,而是利用.map對集合進行迭代,從而返回一個數組。 _.identity該方法傳入的值和返回的值相等。(主要用于迭代)    if (isArrayLike(obj)) return _.map(obj, _.identity);    // 普通對象,則返回由屬性值組成的數組。    return _.values(obj);   };

數據類型

STL需要對vector、list等進行區分是因為不同的數據結構需要或者可以進行不同的實現,但underscore里面Collections和Arrays分開是什么道理呢?這也要從javascript的數據類型說起,看下圖。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 台南市| 仁布县| 隆安县| 合肥市| 侯马市| 云浮市| 天气| 万年县| 安新县| 高台县| 南开区| 东辽县| 佳木斯市| 苍山县| 永善县| 霍林郭勒市| 花垣县| 云浮市| 固阳县| 平塘县| 西峡县| 宝坻区| 济源市| 合肥市| 湘潭县| 永宁县| 交城县| 铜鼓县| 盐源县| 桓仁| 西青区| 阳朔县| 庆安县| 聂荣县| 西峡县| 大足县| 静宁县| 旬阳县| 疏附县| 岐山县| 台山市|