读jQuery之四(优雅的迭代)


Posted in Javascript onJune 20, 2011

jQuery的操作往往是分两步
1,获取元素集合(选择器)
2,操作元素集合
而第二步操作元素集合的主要方法就是jQuery.each。查看源码,我们发现jQuery.each及this.each分别调用了27次和31次。可见它是多么的重要。
这篇将分析下jQuery.each及this.each方法。看看他们如何与jQuery.extend一起扩展jQuery库。最后我会给zChain.js加上each方法。
部分源码如下

jQuery.fn = jQuery.prototype = { 
... 
// Execute a callback for every element in the matched set. 
// (You can seed the arguments with an array of args, but this is 
// only used internally.) 
each: function( callback, args ) { 
return jQuery.each( this, callback, args ); 
}, 
... 
} 
jQuery.extend({ 
... 
// args is for internal usage only 
each: function( object, callback, args ) { 
var name, i = 0, 
length = object.length, 
isObj = length === undefined || jQuery.isFunction( object ); 
if ( args ) { 
if ( isObj ) { 
for ( name in object ) { 
if ( callback.apply( object[ name ], args ) === false ) { 
break; 
} 
} 
} else { 
for ( ; i < length; ) { 
if ( callback.apply( object[ i++ ], args ) === false ) { 
break; 
} 
} 
} 
// A special, fast, case for the most common use of each 
} else { 
if ( isObj ) { 
for ( name in object ) { 
if ( callback.call( object[ name ], name, object[ name ] ) === false ) { 
break; 
} 
} 
} else { 
for ( ; i < length; ) { 
if ( callback.call( object[ i ], i, object[ i++ ] ) === false ) { 
break; 
} 
} 
} 
} 
return object; 
}, 
... 
});

以上可看出,
1,jQuery().each是直接挂在jQuery.prototype(jQuery.fn)上的,因此每个jQuery对象都包含each方法。
2,jQuery.each是通过jQuery.extend({})方式扩展的。前面已经说过,通过这种方式扩展的方法将挂在function jQuery上,即为jQuery类的静态方法。
3,jQuery().each方法中只有一句:return jQuery.each( this, callback, args )。即jQuery对象的each方法实现上其实就是调用jQuery静态的jQuery.each。因此jQuery.each才是关键所在。
下面详细分析jQuery.each,它有三个参数object, callback, args。
1,object可以为数组(Array),对象(Object),甚至是函数类型(Functoin);
2,callback是回调函数,类型为function;
3,args为jQuery库自身使用,使用者不会用到该参数,这里暂不讨论该参数情况。

函数中第一句定义必要的变量

var name, i = 0, 
length = object.length, 
isObj = length === undefined || jQuery.isFunction( object );

length=object.length很好理解,有三种情况length不为undefined
1, object为数组类型(Array)时,数组具有length属性;
2, object为函数类型(Functoin)时,length为该函数定义的参数个数,如果该函数没有定义参数,length为0;
3, 具有length属性的object伪数组(如:arguments,HTMLCollection,NodeList等)。

变量isObj用来判断是否是对象类型,有两种情况为true:
1,变量length等于undefined,即所传object没有length属性。
2,参数object为函数类型

这里强调下object为jQuery对象。即当在$(xx).each时发生,这时会将this传到$.each中。如:return jQuery.each( this, callback, args )。这里第一个参数this即为jQuery对象,每个jQuery对象是具有length属性的。

each中有以下两个分支
1,如果isObj为true,则用for in语句去遍历该对象,如果把每个迭代的对象看出键值对形式的话。callback中的this是值object[name],callback第一个参数是键name,第二个参数是值object[name]。
2,如果isObj为false,则用for循环去遍历数组(类数组)。callback中的this是数组中单独元素的值value,callback第一参数是数组的索引i,第二参数是数组单独元素值value。
callback调用后返回值如果是false则停止迭代,跳出循环。这里用严格"==="来判断是否与false相等。顺便提一下,函数如果没有显示的return,默认返回undefined。

总结下:
1,$(xx).each的each是jQuery对象的方法,它调用静态的jQuery.each。它只用来迭代jQuery对象,jQuery对象可以看成一个伪数组(具有length属性,用索引方式存取)。
2,$.each的each是function jQuery的静态方法(即jQuery.each),可以迭代对象,数组,伪数组,函数。
zChain-04.rar

Javascript 相关文章推荐
JavaScript事件列表解说
Dec 22 Javascript
JavaScript中的parse()方法使用简介
Jun 12 Javascript
jquery实现横向图片轮播特效代码分享
Nov 19 Javascript
使用jQuery处理AJAX请求的基础学习教程
May 10 Javascript
Javascript类型系统之String字符串类型详解
Jun 21 Javascript
BootstrapTable请求数据时设置超时(timeout)的方法
Jan 22 Javascript
详谈innerHTML innerText的使用和区别
Aug 18 Javascript
JavaScript实现的贝塞尔曲线算法简单示例
Jan 30 Javascript
Vue.js的动态组件模板的实现
Nov 26 Javascript
实例讲解vue源码架构
Jan 24 Javascript
分享一个vue项目“脚手架”项目的实现步骤
May 26 Javascript
使用typescript改造koa开发框架的实现
Feb 04 Javascript
火狐4、谷歌12不支持Jquery Validator的解决方法分享
Jun 20 #Javascript
合并table相同单元格的jquery插件分享(很精简)
Jun 20 #Javascript
functional继承模式 摘自javascript:the good parts
Jun 20 #Javascript
jQuery数组处理方法汇总
Jun 20 #Javascript
jQuery UI AutoComplete 使用说明
Jun 20 #Javascript
jQuery 源码分析笔记(3) Deferred机制
Jun 19 #Javascript
jQuery 源码分析笔记(7) Queue
Jun 19 #Javascript
You might like
PHP基础学习之流程控制的实现分析
2013/04/28 PHP
PHP+MySQL实现消息队列的方法分析
2018/05/09 PHP
PHP自动载入类文件函数__autoload的使用方法
2019/03/25 PHP
跟着Jquery API学Jquery之一 选择器
2010/04/07 Javascript
JQuery中html()方法使用不当带来的陷阱
2011/04/07 Javascript
HTML上传控件取消选择
2013/03/06 Javascript
javascript中的绑定与解绑函数应用示例
2013/06/24 Javascript
showModalDialog模态对话框的使用详解以及浏览器兼容
2014/01/11 Javascript
js函数名与form表单元素同名冲突的问题
2014/03/07 Javascript
自己实现ajax封装示例分享
2014/04/01 Javascript
Javascript冒泡排序算法详解
2014/12/03 Javascript
javascript轻量级库createjs使用Easel实现拖拽效果
2016/02/19 Javascript
AngularJS 工作原理详解
2016/08/18 Javascript
windows下vue.js开发环境搭建教程
2017/03/20 Javascript
老生常谈JavaScript面向对象基础与this指向问题
2017/10/16 Javascript
ES6关于Promise的用法详解
2018/05/07 Javascript
Vue2.0 实现移动端图片上传功能
2018/05/30 Javascript
Typescript 中的 interface 和 type 到底有什么区别详解
2019/06/18 Javascript
js中forEach,for in,for of循环的用法示例小结
2020/03/14 Javascript
JavaScript布尔运算符原理使用解析
2020/05/06 Javascript
[01:07]DOTA2次级职业联赛 - Fpb战队宣传片
2014/12/01 DOTA
Python  连接字符串(join %)
2008/09/06 Python
python查找第k小元素代码分享
2013/12/18 Python
Python对list列表结构中的值进行去重的方法总结
2016/05/07 Python
Python实现定时任务
2017/02/08 Python
pycharm第三方库安装失败的问题及解决经验分享
2020/05/09 Python
Python描述数据结构学习之哈夫曼树篇
2020/09/07 Python
Champion官网:美国冠军运动服装
2017/01/25 全球购物
JD Sports意大利:英国篮球和运动时尚的领导者
2017/10/29 全球购物
介绍一下SQL Server的全文索引
2013/08/15 面试题
研究生自我鉴定范文
2013/10/30 职场文书
毕业生的自我评价
2013/12/30 职场文书
党员公开承诺事项
2014/03/25 职场文书
团委书记的竞聘演讲稿
2014/04/24 职场文书
人才市场接收函
2015/01/30 职场文书
MySQL分区表管理命令汇总
2022/03/21 MySQL