成人无码视频,亚洲精品久久久久av无码,午夜精品久久久久久毛片,亚洲 中文字幕 日韩 无码

資訊專欄INFORMATION COLUMN

underscore源碼分析之基礎方法

BigNerdCoding / 2577人閱讀

摘要:在上篇文章整體架構分析中,我們講過上面的方法有兩種掛載方式,一個是掛載到構造函數(shù)上以的形式直接調(diào)用在后文上統(tǒng)稱構造函數(shù)調(diào)用,另一種則是掛到上以的形式被實例調(diào)用在后文上統(tǒng)稱原型調(diào)用。

underscore源碼分析之基礎方法

本文是underscore源碼剖析系列的第二篇,主要介紹underscore中一些基礎方法的實現(xiàn)。

mixin

在上篇文章underscore整體架構分析中,我們講過_上面的方法有兩種掛載方式,一個是掛載到_構造函數(shù)上以_.map(arr)的形式直接調(diào)用(在后文上統(tǒng)稱構造函數(shù)調(diào)用),另一種則是掛到_.prototype上以_(arr).map()的形式被實例調(diào)用(在后文上統(tǒng)稱原型調(diào)用)。

翻一遍underscore源碼你會發(fā)現(xiàn)underscore中的方法都是直接掛到_構造函數(shù)上實現(xiàn)的,但是會通過mixin方法來將_上面的方法擴展到_.prototype上面,這樣這些方法既可以直接調(diào)用,又可以通過實例來調(diào)用。

_.mixin = function(obj) {
    // 遍歷obj上所有的方法
    _.each(_.functions(obj), function(name) {
        // 保存方法的引用
        var func = _[name] = obj[name];
        _.prototype[name] = function() {
            // 將一開始傳入的值放到數(shù)組中
            var args = [this._wrapped];
            // 將方法的參數(shù)一起push到數(shù)組中(這里處理的很好,保證了func方法參數(shù)的順序)
            push.apply(args, arguments);
            // 這里先用apply方法執(zhí)行了func,并將結果傳給了result
            return result(this, func.apply(_, args));
        };
    });
};

_.mixin(_);

從這段代碼中我們可以看出,mixin方法將_上的所有方法通過遍歷的形式掛載到了_.prototype上面。

細心觀察一下,構造函數(shù)調(diào)用和原型調(diào)用的區(qū)別在哪里?
沒錯,區(qū)別就在于調(diào)用方式和傳參,構造函數(shù)調(diào)用時一般會把要處理的值當做第一個參數(shù)傳入,而原型調(diào)用的時候會把要處理的值傳入_構造函數(shù)來創(chuàng)建一個實例。

var arr = [1, 2, 3]
var func = function(item) {
    console.log(item);
}
// 構造函數(shù)調(diào)用時arr被傳入第一個參數(shù)
_.each(arr, func)
// 原型調(diào)用的時候,arr被當做參數(shù)傳給_方法來創(chuàng)建一個實例
_(arr).each(func)
// 鏈式調(diào)用,和上面類似
_.chain(arr).each(func)

從上一節(jié)中我們知道,在創(chuàng)建一個_的實例時,會用this._wrapped將傳入的值保存起來,所以在mixin里面這一句:var args = [this._wrapped];是將我們傳給_的值放到args數(shù)組第一項中,之后再將arguments也放入args數(shù)組中,借助apply方法執(zhí)行當前遍歷的方法(在這個例子中是each),這個時候傳給each方法的是arr和func,正好和原來直接_.each調(diào)用each傳入?yún)?shù)的順序是一樣的(underscore中的方法第一項基本上都是要處理的數(shù)據(jù))。

鏈式調(diào)用

那么上面最后return result(this, func.apply(_, args)),result又是做什么的呢?

首先來看result源碼:

var result = function(instance, obj) {
    // 首先判斷是否使用鏈式調(diào)用,如果是,那就繼續(xù)將剛剛執(zhí)行后返回的結果鏈式調(diào)用一下,如果不是,則直接返回執(zhí)行后的結果
    return instance._chain ? _(obj).chain() : obj;
};
_.chain = function(obj) {
    // 創(chuàng)建一個實例
    var instance = _(obj);
    // 給這個實例加個_chain屬性來表明這是鏈式調(diào)用
    instance._chain = true;
    return instance;
};

我們知道underscore中也是有和jQuery類似的鏈式調(diào)用,來看一下鏈式調(diào)用的例子:

var arr = [1, 2, 3]
var newArr = _.chain(a).map(function(item) {
    return item + 1
}).filter(function(item) {
    return item > 2
}).value()

鏈式調(diào)用的關鍵在于每次執(zhí)行方法后都需要返回一個實例,以確保能夠繼續(xù)調(diào)用其他方法。
chain方法會用傳入的obj創(chuàng)建一個_的實例,這個實例可以調(diào)用原型上的方法。從上面mixin的實現(xiàn)來看,每次調(diào)用原型方法后會將執(zhí)行后的結果傳給result方法,在result內(nèi)部會判斷你是否使用了鏈式調(diào)用(chain),如果是鏈式的,那么就會將返回結果鏈式化(傳入chain中創(chuàng)建新的實例)。
鏈式調(diào)用一定要在結尾執(zhí)行value方法,不然最后返回的是一個對象(最后一次創(chuàng)建的_實例)

數(shù)組函數(shù)

underscore構造方法上面并沒有直接對push、pop、shift等數(shù)組方法進行實現(xiàn),但是鏈式調(diào)用的時候往往需要用到這些方法,所以在原型上對這些方法做了一些封裝,實現(xiàn)方法和mixin類似,這里不再多做解釋。

_.each(["pop", "push", "reverse", "shift", "sort", "splice", "unshift"], function(name) {
    var method = ArrayProto[name];
    _.prototype[name] = function() {
    var obj = this._wrapped;
    method.apply(obj, arguments);
    // 這句是好像是為了解決ie上的bug?
    if ((name === "shift" || name === "splice") && obj.length === 0) delete obj[0];
        return result(this, obj);
    };
});

_.each(["concat", "join", "slice"], function(name) {
    var method = ArrayProto[name];
    _.prototype[name] = function() {
        return result(this, method.apply(this._wrapped, arguments));
    };
});

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

轉載請注明本文地址:http://m.hztianpu.com/yun/93519.html

相關文章

  • underscore源碼剖析整體架構

    摘要:我這里有個不夠準確但容易理解的說法,就是檢查一個對象是否為另一個構造函數(shù)的實例,為了更容易理解,下面將全部以是的實例的方式來說。 underscore源碼分析之整體架構 最近打算好好看看underscore源碼,一個是因為自己確實水平不夠,另一個是underscore源碼比較簡單,比較易讀。本系列打算對underscore1.8.3中關鍵函數(shù)源碼進行分析,希望做到最詳細的源碼分析。今...

    2shou 評論0 收藏0
  • underscore源碼該如何閱讀?

    摘要:所以它與其他系列的文章并不沖突,完全可以在閱讀完這個系列后,再跟著其他系列的文章接著學習。如何閱讀我在寫系列的時候,被問的最多的問題就是該怎么閱讀源碼我想簡單聊一下自己的思路。感謝大家的閱讀和支持,我是冴羽,下個系列再見啦 前言 別名:《underscore 系列 8 篇正式完結!》 介紹 underscore 系列是我寫的第三個系列,前兩個系列分別是 JavaScript 深入系列、...

    weknow619 評論0 收藏0
  • underscore.js 源碼分析 _.each() 函數(shù)

    摘要:遍歷中的所有元素,按順序用遍歷輸出每個元素。如果傳遞了參數(shù),則把綁定到對象上。返回以方便鏈式調(diào)用。 each _.each(list, iteratee, [context])?Alias:?forEach?遍歷list中的所有元素,按順序用遍歷輸出每個元素。如果傳遞了context參數(shù),則把iteratee綁定到context對象上。每次調(diào)用iteratee都會傳遞三個參數(shù):(ele...

    xbynet 評論0 收藏0
  • underscore源碼解讀debounce

    摘要:直接來分析返回的匿名函數(shù)部分。我第一次調(diào)用事件函數(shù)是在,按照設定,之后才能調(diào)用第二次方法,在這秒內(nèi),任何調(diào)用都是不執(zhí)行的。這個難點解決了,其他就都好說。恩,那這個的解讀就結束了,有什么地方我沒寫清楚的話,請給我留言。 剛寫完一篇debounce(防抖)函數(shù)的實現(xiàn),我又看了下underscore.js的實現(xiàn)方法。算是趁熱打鐵,分析一下underscore里實現(xiàn)的套路。 先貼上源碼: _....

    Flink_China 評論0 收藏0
  • JavaScript專題系列20篇正式完結!

    摘要:寫在前面專題系列是我寫的第二個系列,第一個系列是深入系列。專題系列自月日發(fā)布第一篇文章,到月日發(fā)布最后一篇,感謝各位朋友的收藏點贊,鼓勵指正。 寫在前面 JavaScript 專題系列是我寫的第二個系列,第一個系列是 JavaScript 深入系列。 JavaScript 專題系列共計 20 篇,主要研究日常開發(fā)中一些功能點的實現(xiàn),比如防抖、節(jié)流、去重、類型判斷、拷貝、最值、扁平、柯里...

    sixleaves 評論0 收藏0

發(fā)表評論

0條評論

閱讀需要支付1元查看
<