`

jQuery中回调函数的原理及实现下

阅读更多
//测试Chrome版本  40.0.2214.115 m

//如有错误欢迎指出

//回调函数分析上 http://ezizoo.iteye.com/blog/2204399  
//下面所讲是回调函数下

//重点
//此次添加 回调函数的三种状态
//所写的js可直接放入html中运行


//首先三种状态都在什么时候做判断
//onece 也就是执行回调的时候 fire()的时候判断是否已经fired==true
//unique 在添加函数的判断数组中是否有这个函数
//memory 在添加函数加上一句判断,当memory为真时,那么在cb.fire()执行后添加的方法也会被再次fire()
//需要有一个记录回调到哪一个函数的下标

//思路已经说了,看代码可直接到Callbacks方法这


//下面的一些方法前面都做了分析
//如有不懂可以看下我以前对这些方法的说明

var toString={}.toString;
var class2type={};
var hasOwn={}.hasOwnProperty;
var isArray=Array.isArray;
var indexOf=[].indexOf;

var each=function(obj,callback){
	var 
		value,
		length=obj.length,
		i=0,
		isArray=isArrayLike(obj);
		//两种情况
		//类数组
		if(isArray){
			for(;i<length;i++){
				//若是返回false,则直接跳出
				value=callback.call(obj,i,obj[i]);
				if(value===false){
					break;
				}
			}
		}else{
			for(i in obj){
				value=callback.call(obj,i,obj[i]);
				if(value===false){
					break;
				}
			}
		}
		return obj;
};

//第二个判断是否像数组一样的对象

var isArrayLike=function(obj){
	var 
		length=obj.length;
		
	//判断为空
	if(obj==null){
		return false;
	}
	
	if(type(obj)==="object" ||typeof(obj)==="function"){
		return false;
	}
	
	return type(obj)==="array" ||length===0 || (length>0 &&(length-1) in obj);
};

//第三个判断类型
var type=function(obj){
	//排除为空的
	if(obj==null){
		return obj+"";
	}
	//做判断,如果是object或者function类型的时候
	//不是执行后面
	return  typeof obj==="object" ||typeof obj==="function"  ? class2type[toString.call(obj)] : typeof obj;
};

each("Boolean Number String Function Array Date RegExp Object Error".split(" "),function(_,name){
	class2type["[object "+name+"]"]=name.toLowerCase();  
});

var isFunction=function(obj){
	return type(obj);
};
var isWindow=function(obj){
	return obj!==null && obj.window===window;
};

var isPlainObject=function(obj){

	if(type(obj)!=="object" ||obj.nodeType||isWindow(obj)){
		return false;
	}
	if(hasOwn.call(obj.constructor.prototype,"isPrototypeOf")){
		return true;
	}
	
};

//一个确定数组中是否存在这个值的函数
var inArray=function(arr,elem,i){
	return arr===null ? -1 :indexOf.call(arr,elem,i);
};

//第一个添加onece
//第二个添加memory  //只要在添加函数的时候过滤掉就行
var Callbacks=function(options){
	options=type(options)==="string" ? createOptions(options) :{};
	var 
		i,
		fired,
		firing,
		list=[],
		fireIndex=list.length,
		stack=!options.onece && [];
		//定义一个函数,将数组全部执行一次
		fire=function(){
			for(;list && fireIndex<list.length;i++,fireIndex++){
				//list[i]();
				//alert(this);
				list[fireIndex].call(arguments[0]);
			}
			fired=true;
		},
		self={
			add:function(){
				(function add(args){
					//对传进来的参数进行解析
					//以后可使用each遍历
					for(i=0;i<args.length;i++){
						if(!options.unique && typeof(args[i])==="function"||(options.unique && inArray(list,args[i])<0)){
							//list[i]=arguments[i]; 
							list.push(args[i]);
						}
					}
				})(arguments);
				
				if(options.memory){
					fire(this);
				}
				return this;
			},
			fire:function(){
				//if(options.onece && fired){
				//	fire(this);
				//}else{	
				//}
				//若是写成上述,当onece为false时,第一次就过不去
				//再写个fireWith()方法
				self.fireWith(this);
				return this;
			},
			fireWith:function(){
				if(list && (!fired || stack)){
					fire(this);
				}
				return this;
			}
		};
	return self;
};

//写个函数将几种状态解析出来
//参数形式如下'onece','memory'
var createOptions1=function(){
	var object={};
	each(arguments,function(_,flag){
		object[flag]=true;
	});
	return object;
};

//换一种写法
//参数形式如下'onece memory'
var reg=/\S+/g;
var createOptions=function(){
	var object={};
	each(arguments[0].match(reg),function(_,flag){
		object[flag]=true;
	});
	return object;
};

console.info(createOptions('onece unique'));

//附件中有html测试

 

分享到:
评论

相关推荐

    jQuery回调函数的定义及用法实例

    主要介绍了jQuery回调函数的定义及用法,以实例形式详细分析了回调函数的原理与实现技巧,具有一定的参考借鉴价值,需要的朋友可以参考下

    Web前端Ajax&JQuery视频教程课件

    本套Java教程涵盖Ajax的实现原理,XMLHttpRequest实现Ajax,回调函数,Ajax数据交换格式(HTML、XML、JSON),Ajax发送GET和POST请求,异步编程模型和同步编程模型,解决Ajax的GET请求缓存问题,使用Ajax验证用户名...

    超实用的jQuery代码段

    1.9 不可不知的Callback回调 1.10 提高效率的链式(Chaining)操作 1.11 在新窗口中打开链接 1.12 强制在弹出窗口中打开链接 1.13 平滑滚动页面到某个锚点 1.14 阻止文本行换行 1.15 实现iframe高度自适应 1.16 实现...

    js框架jquery实现幸运大转盘抽奖程序代码,兼容多种浏览器.zip

     callback:function(){}, //回调函数 06  easing:$.easing.easeOutSine // $.easing.easeInOutExpo 运动的效果,需要引用jquery.easing.min.js的文件 07  }) 08 09 $("触发转动元素").rotate(45); //转动45 10 ...

    jQuery链式操作如何实现以及为什么要用链式操作

    两个问题 1.jQuery的链式操作是如何实现的? 2.为什么要用链式操作? 大家认为这两个问题哪个好回答一点呢? 链式操作 原理相信百度一下一大把,实际上链式操作仅仅是通过对象上的方法最后 return this 把对象再返回...

    jQuery小动画效果.zip

    效果描述: 一个原理很简单的基于jQuery插件库的图片动画效果 ...主要采用animate动画属性以及回调函数实现 效果一气呵成 使用方法: 1、将head中的样式引入到你的样式表中 2、将body中的代码部分拷贝过去即可

    懒人原生jQuery小动画效果

    主要采用animate动画属性以及回调函数实现 效果一气呵成 使用方法: 1、将head中的样式引入到你的样式表中 2、将body中的代码部分拷贝过去即可 (注意保持图片路径正确即可)

    Jquery跨域获得Json时invalid label错误的解决办法

    最后,仔细安静下来,细读 json 官方文档后发现这么一段: JSON数据是一种能很方便通过JavaScript解析的结构化数据。... 其实jquery跨域的原理是通过外链 [removed] 来实现的,然后在通过回调函数加上回调

    jQuery使用eraser.js插件实现擦除、刮刮卡效果的方法【附eraser.js下载】

    jquery.eraser插件的原理是用一个画布遮住图片,然后根据触摸或鼠标输入来擦除画布显示图片,您可以在参数中指定一个回调函数设置画笔大小。 使用需知: 必须确保图片是完全加载之后调用eraser(),否则它不会工作。...

    jQuery小动画效果特效代码

    效果描述: 一个原理很简单的基于jQuery插件库的图片动画效果 主要采用animate动画属性以及回调函数实现 效果一气呵成 使用方法: 1、将head中的样式引入到你的样式表中 2、将body中的代码部分拷贝过去即可

    使用jquery的jsonp如何发起跨域请求及其原理详解

    前言 本文主要给大家介绍的是关于jquery jsonp发起跨域请求及其原理的相关内容,分享出来供大家参考学习,下面话不多说了,来一起看看...这里讲下使用jquery的jsonp如何发起跨域请求及其原理。 先看下准备环境:两个

    JQuery 插件制作实践 xMarquee插件V1.0

    (注:利用移动后的回调函数可以方便做一个相册插件,有兴趣的自己写下)。做开发的人要记住一句话:Do the simplest thing that could possibly work!做最简单可用的东东,千万别过分设计。 xM

    mvvm:多种方式实现mvvm

    #多种方式实现mvvm#目录pubsub /...3、实现一个Watcher(订阅者),作为连接Observer和Compile的桥梁,能够订阅并收到每个属性变动的通知,执行指令绑定的相应回调函数,从而更新视图。4、mvvm入口函数,整合以上三者/

    原生JavaScrpit中异步请求Ajax实现方法

    一般来说,使用Jquery中的$.ajax,$.post,$.getJSON,非常方便,但是有的时候,我们只因为需要ajax功能而引入Jquery比较不划算。 所以接下来便用原生JavaScrpit实现一个简单的Ajax请求,并说明ajax请求中的跨域访问...

    python入门到高级全栈工程师培训 第3期 附课件代码

    08 数学意义的函数与python中的函数 09 为何要有函数 10 函数返回值 11 可变长参数 第15章 01 上节课复习 02 全局变量与局部变量 03 风湿理论之函数即变量 04 函数递归 05 函数递归补充 第16章 01 上节课回顾 02...

    原生JavaScript实现Ajax异步请求

    一般来说,使用Jquery中的$.ajax,$.post,$.getJSON,非常方便,但是有的时候,我们只需要ajax功能,这样引入Jquery比较不划算。 所以接下来便用原生JavaScrpit实现一个简单的Ajax请求,并说明ajax请求中的跨域访问...

    深入分析jsonp协议原理

    今天在开发联调的过程中,需要跨域的获取数据,因为使用的jquery,当然使用dataType:’jsonp’就能够很easy的解决了。 但是因为当时后端没有支持jsonp来访问,后来他在实现这个功能的时候问了我一句,jsonp形式返回...

Global site tag (gtag.js) - Google Analytics