成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

underscore.js 源碼分析之 _.each() 函數(shù)

xbynet / 3339人閱讀

摘要:遍歷中的所有元素,按順序用遍歷輸出每個(gè)元素。如果傳遞了參數(shù),則把綁定到對(duì)象上。返回以方便鏈?zhǔn)秸{(diào)用。

each _.each(list, iteratee, [context])?Alias:?forEach?
遍歷list中的所有元素,按順序用遍歷輸出每個(gè)元素。如果傳遞了context參數(shù),則把iteratee綁定到context對(duì)象上。每次調(diào)用iteratee都會(huì)傳遞三個(gè)參數(shù):(element, index, list)。如果list是個(gè)JavaScript對(duì)象,iteratee的參數(shù)是?(value, key, list))。返回list以方便鏈?zhǔn)秸{(diào)用。

_.each([1, 2, 3], alert);
=> alerts each number in turn...
_.each({one: 1, two: 2, three: 3}, alert);
=> alerts each number value in turn...

_.each 源碼

  // The cornerstone, an `each` implementation, aka `forEach`.
  // Handles raw objects in addition to array-likes. Treats all
  // sparse array-likes as if they were dense.
  _.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;
  };

分析

_.each([1, 2, 3], alert); // _.each()使用方法,其中`alert`可以換成自己寫的function

obj[1, 2, 3] , iterateealert , context 沒(méi)有

iteratee = optimizeCb(iteratee, context);

首先是調(diào)用optimizeCb()函數(shù)

分析 optimizeCb 源碼

var optimizeCb = function(func, context, argCount) {
    if (context === void 0) return func;
};

因?yàn)?b>context 沒(méi)有,所以這里直接返回alert , 所以 iteratee 現(xiàn)在是alert

再使用 isArrayLike 判斷 傳進(jìn)來(lái)的obj是不是數(shù)組,判斷數(shù)組的方法

//原理就是通過(guò)判斷它是否具有長(zhǎng)度且長(zhǎng)度大于0且小于MAX_ARRAY_INDEX
var MAX_ARRAY_INDEX = Math.pow(2, 53) - 1;
var getLength = property("length");
var isArrayLike = function(collection) {
    var length = getLength(collection);
    return typeof length == "number" && length >= 0 && length <= MAX_ARRAY_INDEX;
  };

因?yàn)檫@里是數(shù)組,所以繼續(xù)

// 通過(guò) for 循環(huán)來(lái)遍歷數(shù)組里面每一個(gè)值,傳給 iteratee 函數(shù)來(lái)運(yùn)行
for (i = 0, length = obj.length; i < length; i++) {
  iteratee(obj[i], i, obj); // 等于 alert(obj[i], i, obj);
}

如果不是數(shù)組呢?對(duì)象默認(rèn)是沒(méi)有length 屬性的

var keys = _.keys(obj);
for (i = 0, length = keys.length; i < length; i++) {
  iteratee(obj[keys[i]], keys[i], obj);
}

使用了_.keys() 函數(shù),下面分析 _keys() 源碼

_.keys = function(obj) {
    if (!_.isObject(obj)) return [];
    if (nativeKeys) return nativeKeys(obj);
    var keys = [];
    for (var key in obj) if (_.has(obj, key)) keys.push(key);
    // Ahem, IE < 9.
    if (hasEnumBug) collectNonEnumProps(obj, keys);
    return keys;
};

首先使用_.isObject函數(shù)判斷是不是對(duì)象

// Is a given variable an object?
  _.isObject = function(obj) {
    var type = typeof obj;
    return type === "function" || type === "object" && !!obj;
  };

首先判斷傳進(jìn)來(lái)的參數(shù)的類型,然后返回true或者false

注意,通過(guò)以下兩個(gè)例子可知, && 的優(yōu)先級(jí)比 || 的高

console.log(true || false && false) // true
console.log(true || false && true) // true 

然后如果瀏覽器支持 ES5Object.keys 方法,就優(yōu)先使用

nativeKeys = Object.keys,

不支持就繼續(xù)遍歷循環(huán) 對(duì)象

var keys = [];
// own enumerable properties
for (var key in obj)
// hasOwnProperty
if (_.has(obj, key)) keys.push(key);

使用了 _.has() 函數(shù),下面解析_.has()函數(shù)

// Shortcut function for checking if an object has a given property directly
// on itself (in other words, not on a prototype).
_.has = function(obj, key) {
  return obj != null && hasOwnProperty.call(obj, key);
};

通過(guò)判斷 傳進(jìn)來(lái)的obj 是否為null 并且調(diào)用hasOwnProperty 方法判斷該對(duì)象是否有該鍵值

hasOwnProperty   = ObjProto.hasOwnProperty = Object.prototype.hasOwnProperty;

如果有該屬性,返回true ,這時(shí)回到_.keys() ,該簡(jiǎn)直pushkeys[] 內(nèi)

// IE9以下不能用 for in 來(lái)遍歷,所以使用collectNonEnumProps()函數(shù)來(lái)解決問(wèn)題,暫時(shí)可以不看
if (hasEnumBug) collectNonEnumProps(obj, keys);

這時(shí)已經(jīng)把對(duì)象轉(zhuǎn)化成數(shù)組了,回到_.each() 函數(shù),繼續(xù)使用for 循環(huán)遍歷數(shù)組 ,把參數(shù)傳遞給alert函數(shù)

for (i = 0, length = keys.length; i < length; i++) {
  iteratee(obj[keys[i]], keys[i], obj); //  等于 alert(obj[keys[i]], keys[i], obj);
}

最后再返回obj

整個(gè)分析_.each() 函數(shù),相繼分析了_.has()_.keys() 函數(shù),大概看了一下underscore.js 的源碼,感覺(jué)不是太難,一個(gè)函數(shù)一個(gè)函數(shù)分析就好。

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/80826.html

相關(guān)文章

  • 學(xué)習(xí) underscore 源碼整體架構(gòu),打造屬于自己的函數(shù)式編程類庫(kù)

    摘要:譯立即執(zhí)行函數(shù)表達(dá)式處理支持瀏覽器環(huán)境微信小程序。學(xué)習(xí)整體架構(gòu),利于打造屬于自己的函數(shù)式編程類庫(kù)。下一篇文章可能是學(xué)習(xí)的源碼整體架構(gòu)。也可以加微信,注明來(lái)源,拉您進(jìn)前端視野交流群。 前言 上一篇文章寫了jQuery整體架構(gòu),學(xué)習(xí) jQuery 源碼整體架構(gòu),打造屬于自己的 js 類庫(kù) 雖然看過(guò)挺多underscore.js分析類的文章,但總感覺(jué)少點(diǎn)什么。這也許就是紙上得來(lái)終覺(jué)淺,絕知此...

    junnplus 評(píng)論0 收藏0
  • underscore源碼學(xué)習(xí)(一)

    摘要:所以,剛開(kāi)始,我從源碼比較短的包含注釋只有行開(kāi)始學(xué)習(xí)起。一般,在客戶端瀏覽器環(huán)境中,即為,暴露在全局中。學(xué)習(xí)以后判斷直接使用看起來(lái)也優(yōu)雅一點(diǎn)滑稽臉。在的函數(shù)視線中,的作用執(zhí)行一個(gè)傳入函數(shù)次,并返回由每次執(zhí)行結(jié)果組成的數(shù)組。 前言 最近在社區(qū)瀏覽文章的時(shí)候,看到了一位大四學(xué)長(zhǎng)在尋求前端工作中的面經(jīng),看完不得不佩服,掌握知識(shí)點(diǎn)真是全面,無(wú)論是前端后臺(tái)還是其他,都有涉獵。 在他寫的文章中,有...

    gclove 評(píng)論0 收藏0
  • underscore 0.1.0版本源碼閱讀

    摘要:前面的的目的在于利用自定義拋出錯(cuò)誤令遍歷停止如果是數(shù)組直接過(guò)濾輸出不是數(shù)組遍歷操作壓入數(shù)組返回有點(diǎn)像,過(guò)濾符合條件的注意感嘆號(hào)取反有點(diǎn)像設(shè)置默認(rèn)迭代器判斷是否存在即需要所有元素都滿足迭代條件。 前言 這篇文章是為之后的underscore現(xiàn)版本的源碼做鋪墊,先感受下最先版本 0.1.0版本足夠小 這個(gè)版本已經(jīng)有將近小10年的歷史了 還是有一些不錯(cuò)的地方。 0.1.0版本源碼分析 ...

    Coly 評(píng)論0 收藏0
  • underscore.js 源碼解讀】常用類型判斷以及一些有用的工具方法

    摘要:最近開(kāi)始看源碼,并將源碼解讀放在了我的計(jì)劃中。今天就跟大家聊一聊中一些常用類型檢查方法,以及一些工具類的判斷方法。用是否含有屬性來(lái)判斷工具類判斷方法接下來(lái)看下一些常用的工具類判斷方法。 Why underscore 最近開(kāi)始看 underscore.js 源碼,并將 underscore.js 源碼解讀 放在了我的 2016 計(jì)劃中。 閱讀一些著名框架類庫(kù)的源碼,就好像和一個(gè)個(gè)大師對(duì)話...

    tanglijun 評(píng)論0 收藏0
  • Underscore源碼中文注釋(轉(zhuǎn))

    摘要:創(chuàng)建一個(gè)全局對(duì)象在瀏覽器中表示為對(duì)象在中表示對(duì)象保存下劃線變量被覆蓋之前的值如果出現(xiàn)命名沖突或考慮到規(guī)范可通過(guò)方法恢復(fù)被占用之前的值并返回對(duì)象以便重新命名創(chuàng)建一個(gè)空的對(duì)象常量便于內(nèi)部共享使用將內(nèi)置對(duì)象的原型鏈緩存在局部變量方便快速調(diào)用將 // Underscore.js 1.3.3 // (c) 2009-2012 Jeremy Ashkenas, DocumentCloud Inc....

    Guakin_Huang 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<