jquery原始碼解讀之callbacks篇

2022-08-22 13:03:14 字數 4400 閱讀 4492

callbacks模組通過維護乙個**函式列表,來實現對**函式地管理。其操作包括增加,觸發,移除,清空,禁用,鎖定等,是jquery.defrred, jquery.ajax, jquery.ready等依賴的底層模組。

let cblist = $.callbacks('

once memory');

let fn = (args) =>

cblist.add( fn);

cblist.fire(

'will fire

');

add(fn || fncollections)

增加乙個或多個**函式到內部**函式列表中

fire(args)

將給定的引數挨個傳進**函式列表中的函式,並執行

**函式執行的上下文是當前callbacks

firewith(context, args)

將給定的引數挨個傳進**函式列表中的函式,並執行

**函式執行的上下文是當前傳入的context

disable

禁用任何新增和觸發操作,刪除**函式列表,清空記憶值,清空引數記憶陣列,終止**函式中所有操作

lock

禁用callbacks的觸發操作

如果當前不是memory模式且**函式列表並沒有在執行,則相當於disable操作

否則,只會禁用觸發操作,後續的新增操作不會受影響

remove(fn)

從**函式列表中移除fn

empty()

清空**函式列表

has(fn)

判斷fn是否在當前**函式列表中,如果fn為空,則判斷當前**函式列表是否為空

locked()

判斷當前**函式列表是否處於鎖定狀態

disabled()

返回當前**函式列表的禁用狀態

整體結構

/*

1. 工具函式

2. 將以空格為分隔的字串轉為物件

*/function

createoptions(options)

let callbacks = function

(options) ;

/*定義下面函式需要的各種變數

+. list **函式列表

+. firing 當前**函式是否在執行

+. fired 當前**函式列表是否至少已經執行過一次

+. locked 當前**函式列表是否被鎖定

+. disabled 當前**函式列表是否被禁用

+. queue 儲存**函式列表觸發時傳入的引數,是個二維陣列,每次傳入[context, args]

+. memory 這個值標示queue的值如何處理,值存在多種情況

> + options.memory不存在,memory為false

> + **函式執行返回false且存在stoponfalse標示時

> + 禁用狀態下 memory值為空字串

> + 鎖定狀態下,如果不存在memory標示,且**函式列表並沒有在執行,此時memory為空字串

> + 其它情況 memory = [context, args], 用來獲取queue中儲存的記憶引數

*///

定義乙個物件用來儲存callbacks的各種方法,如下

let self =,

fire:

function

() {},

firewith:

function

() {},

remove:

function

() {},

empty:

function

() {},

has:

function

() {},

lock:

function

() {},

disable:

function

() {},

disabled:

function

() {}

}return

self;

}

核心工具函式

fire 具體觸發過程

/*

設定當前**列表的鎖定狀態

表示當前**列表已經觸發

*/locked = locked ||options.once;

fired = firing = true;

//

當陣列長度大於0時執行for迴圈體,如果陣列長度小於等於0,將fireingindex重置為-1

for(; queue.length; firingindex = -1)

}}

if (!options.memory) 

if(locked)

else

}

函式詳解

(1) add 增加乙個或者多個函式到**函式列表中

如果是在memory模式下,增加的函式會立即執行,其執行的上下文為memory[0],執行的引數是memory[1]
/*

如果在memory模式下且**函式列表沒有被觸發,則設定正在觸發的**函式索引為

**函式列表長度減一,並將上一次觸發的引數存入queue

*/if (memory && !firing)

//

使用乙個立即執行函式來進行函式追加

(function

(args) )(arguments)

//

如果在memory模式下且當前**函式列表沒有在執行,就呼叫fire方法

if (memory && !firing)

(2) firewith

let firewith: function

(context, args)

//如果當前**列表沒有正在執行,則觸發**函式列表執行

if (!firing)

}return

this

;}

(3) fire(args)

//

fire實際上是firewith呼叫的一種特殊情況,

//此時context為**管理物件本身

let fire = function

(args)

(4) lock

/*

1.設定locked和queue等於空陣列

2. 這裡有個疑問為什麼不直接設定locked為true呢,其實空陣列就是等於true

3. 如果memory為false或者為空,且當前**函式列表尚沒有執行,則徹底刪除

**函式列表, 設定memory等於空字串。

*/locked = queue =;

if (!memory && !firing)

return

this;

(5) disable()

locked =queue;

list = memory = '';

return

this;

(6) locked()

return !!locked

(7) disabled()

/*

判斷列表是否禁用

*/return !list

(8) empty()

//

清空列表

if(list)

(9) has(fn)

//

判斷函式是否在**函式列表,如果fn為空,則判斷該函式列表是否長度大於0

//$.inarray(data, list, index) 返回某個資料在列表中的位置 類似於indexof

return fn ? $.inarray(fn, list) > -1 ? list.length > 0;

(10) remove(fn)

let remove = function

(...fns) }})

}

jQuery原始碼解讀之init函式

直接new了乙個物件。同時根據jquery.fn jquery.prototype,jquery.fn相當於jquery.prototype。jquery function selector,context init jquery.fn.init function selector,context,...

jQuery原始碼解讀一

前言 我為什麼要看這個原始碼,很簡單,尋找我自己寫的js框架與jquery之間的差異,取長補短,最終目標是提高js程式設計的乙個眼界,看看別人是怎麼想的,因為自己乙個人的想法往往是片面的,也為了能讓自己的主觀漸漸接近客觀事實。雖然jquery框架能直接拿來用,但是對於偏愛研究的人來說,還是喜歡寫原生...

jquery原始碼解讀1

function global,factory returnfactory w else pass this if window is not defined yet typeofwindow undefined window this,function window,noglobal 其中形參gl...