jQuery源码阅读(十二)---Callbacks回调对象
来源:互联网 发布:换域名 编辑:程序博客网 时间:2024/05/17 07:25
还记得jQuery源码阅读(一)的时候,整理了jQuery库的整体架构,主要分为三个模块:
入口模块、底层支持模块和功能模块,各个模块之间也是有关联的。
前面几篇博文分别分析了jQuery库的入口模块,最主要的是init方法的分析;还分析了jQuery底层支持模块中的工具方法,主要是通过jQuery.extend()方法来扩展jQuery静态方法的。底层支持模块中,出了工具方法之外,还有很多模块,个人觉得这些模块的一个作用就是增强代码的复用性和易用性。比如回调对象模块,异步队列模块,延迟对象,队列,数据缓存,浏览器支持模块,Sizzle选择器模块等等。这次主要先整理jQuery中的回调对象。
源码框架及使用
jQuery.Callbacks = function(flags){ add = function(){ } fire = function(){ } self = { //定义了一些变量 //下面是用来管理函数的方法 add: function(){ }, fire: function(){ }, fireWith: function(){ }, has: function(){ }, fired: function(){ }, lock: function(){ }, locked: function(){ } //等等 } return self;}
由上面架构可以知道,jQuery.Callbacks函数主要是返回一个回调对象,这个回调对象通过一些方法来管理回调函数。具体什么方法呢?有add(),fire(),fireWith(),lock()等等很多方法,主要是通过将函数加入到数组列表中的方式,然后一个个去执行从而达到管理函数的目的。
可以看到,Callbacks方法里面,定义了两个私有函数,为什么要这么做呢?
我的理解是:为了减少内存的占用。因为Callbacks函数最终是要返回一个回调对象的,而回调对象中有管理函数的一些方法,如果把这些方法直接写到回调对象中,也是可以的,但是这就意味着每个回调对象都会有一份自己的方法,只是这些方法都是同名的,这就导致内存的浪费。而把add和fire定义成两个私有的变量,不管调用多少次jQuery.Callbacks方法,返回的回调对象中的方法都会去调Callbacks函数中的私有方法,并且指向的是相同的内存地址。
下来我们看下jQuery.Callbacks的参数情况:
1. once //只执行一遍函数,不会重复执行2. memory //会将所有add进函数列表的函数执行3. unique //不允许列表中有相同的函数4. stopOnFalse //对于返回值为false的函数,执行之后停止对后面函数的执行
首先来体会下这几个参数的作用:
function a1(){ console.log('111'); return false;}function a2(){ console.log('222');}
分别展示四组图来显示Callbacks中四个参数的意义:
- once标志
- memory标志
- unique标志
- stopOnFalse标志
从上面四组图可以很容易理解四个参数的含义,那么这四个参数具体在源码中是如何影响的?我想用下面的图来说明
源码分析
根据上面那个图,我们就大致应该知道:
add函数中,将函数fn Push到list数组里,同时会判断unique和memory两个参数,如果unique参数为真,那么不会将相同的函数都push到数组里;如果memory为真,会add之后再调一次fire函数。
fire函数中,将数组中所有的函数进行执行,同时会判断once和stopOnFalse两个参数。如果once为真,只会将所有函数执行一遍;如果stopOnFalse为真,那么对于返回值为false的函数,执行之后不会再对后面的函数执行。
基于上面两块思路来看源码,会更好理解一些。
add方法
回调对象中的add方法:
add: function() { if ( list ) { var length = list.length; //这里的add方法是Callbacks函数中的私有方法 add( arguments ); if ( firing ) { firingLength = list.length; } else if ( memory && memory !== true ) { //判断memory参数,并且调fire函数 firingStart = length; fire( memory[ 0 ], memory[ 1 ] ); } } return this;}
Callbacks函数中的私有add方法:
add = function( args ) { var i, length, elem, type, actual; for ( i = 0, length = args.length; i < length; i++ ) { elem = args[ i ]; type = jQuery.type( elem ); if ( type === "array" ) { //如果参数为数组,再递归调add方法 add( elem ); } else if ( type === "function" ) { //判断unique标志,并且看list数组中是否有该函数 if ( !flags.unique || !self.has( elem ) ) { list.push( elem ); } } }}
fire方法
self对象中的fire函数:
fire: function() { //fire方法去调self对象的fireWith方法,该方法不仅将当前作用域传了进去,还将fire中的参数也传进去了 self.fireWith( this, arguments ); return this;}
fireWith: function( context, args ) { if ( stack ) { //一开始stack为空数组,转换成Boolean值也是真;设置了once,会将stack置为undefined,所以重复的fire都不会真正执行 if ( firing ) { //firing这个标志是解决嵌套调用fire的情况;与stack结合起来处理,stack用于保存上下文和参数 if ( !flags.once ) { stack.push( [ context, args ] ); } } else if ( !( flags.once && memory ) ) { //第一次执行或者未设置once参数多次执行 fire( context, args ); } } return this;}
fire = function( context, args ) { args = args || []; //如果未设置memory参数,那么memory变量为true; memory = !flags.memory || [ context, args ]; fired = true; firing = true; firingIndex = firingStart || 0; firingStart = 0; firingLength = list.length; for ( ; list && firingIndex < firingLength; firingIndex++ ) { //对list中每一个函数执行,如果返回false并且stopOnFalse参数为真,那么跳出循环,不再对后面的函数执行。 if ( list[ firingIndex ].apply( context, args ) === false && flags.stopOnFalse ) { memory = true; // Mark as halted break; } } firing = false; if ( list ) { if ( !flags.once ) { if ( stack && stack.length ) { memory = stack.shift(); self.fireWith( memory[ 0 ], memory[ 1 ] ); } } else if ( memory === true ) { self.disable(); //这个用于将stack标记设为undefined } else { list = []; } }}
对于Callbacks回调模块,主要就是这两个函数,当然,还有像self.has
, self.empty
, self.lock
, self.disable
等方法,不过相比来说,这几个方法都比较好理解。这里大概提下lock和disable方法,lock方法是禁止后面的fire函数; 而disable方法会禁止后面要执行的所有操作。总体上来说,Callbacks模块,如果能考虑到所有的情况,并可以沿着源码走一遍,那么对于整个模块已经理解得差不多了。
- jQuery源码阅读(十二)---Callbacks回调对象
- jQuery 2.0.3 源码分析 回调对象 - Callbacks
- jQuery源码阅读之jQuery.Callbacks ()
- jQuery源码解析--回调模块($.Callbacks())
- 阅读jquery--Callbacks
- jQuery源码学习(版本1.11)-Callbacks
- JQuery源码浅析: Callbacks
- jQuery源码之Callbacks详解
- jquery源码分析之Callbacks
- jQuery源码分析-----CallBacks--memory
- jQuery源码阅读之获取jQuery对象
- Jquery.callbacks源码分析-jquery1.8.3
- jquery中Callbacks对象的实现
- Spring源码阅读(十二)—事务
- jQuery Callbacks
- jQuery.Callbacks
- jQuery.Callbacks()
- jQuery源码分析: 如何安全地访问一个数组?(jQuery.Callbacks)
- python学习笔记(十)标准库pprint
- 模板模式
- 初识C++
- dup, dup2, dup3
- 安装SCL后仍然提示lmgrd: Command not found.的解决办法
- jQuery源码阅读(十二)---Callbacks回调对象
- 使用RTL-SDR和Matlab Simulink玩转软件无线电(二十四)
- php+memcache和openresty+memcache
- Java中常见程序:万年历,进制转换等
- 记录一下本周的主要工作及遇到的问题
- CentOS7配置redis
- mir2的db数据库
- Vue2.0子同级组件之间数据交互
- C#