读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 相关文章推荐
监控 url fragment变化的js代码
Apr 19 Javascript
onkeypress字符按键兼容所有浏览器使用介绍
Apr 24 Javascript
javascript实现树形菜单的方法
Jul 17 Javascript
基于javascript实现仿百度输入框自动匹配功能
Jan 03 Javascript
jQuery插件ContextMenu自定义图标
Mar 15 Javascript
jQuery用户头像裁剪插件cropbox.js使用详解
Jun 07 jQuery
在 Node.js 中使用原生 ES 模块方法解析
Sep 19 Javascript
浅谈Redux中间件的实践
Jul 27 Javascript
Vue Autocomplete 自动完成功能简单示例
May 25 Javascript
json解析大全 双引号、键值对不在一起的情况
Dec 06 Javascript
Vue(定时器)解决mounted不能获取到data中的数据问题
Jul 30 Javascript
基于Vue.js+Nuxt开发自定义弹出层组件
Oct 09 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中的替代语法简介
2014/08/22 PHP
php实现paypal 授权登录
2015/05/28 PHP
php设计模式之职责链模式实例分析【星际争霸游戏案例】
2020/03/27 PHP
屏蔽Flash右键信息的js代码
2010/01/17 Javascript
jQuery Validation插件remote验证方式的Bug解决
2010/07/01 Javascript
探索Emberjs制作一个简单的Todo应用
2012/11/07 Javascript
jquery 事件冒泡的介绍以及如何阻止事件冒泡
2012/12/25 Javascript
基于jquery实现轮播焦点图插件
2016/03/31 Javascript
微信小程序中单位rpx和rem的使用
2016/12/06 Javascript
canvas实现爱心和彩虹雨效果
2017/03/09 Javascript
JS实现动态添加DOM节点和事件的方法示例
2017/04/28 Javascript
js中document.write和document.writeln的区别
2018/03/11 Javascript
Vue.js 实现数据展示全部和收起功能
2018/09/05 Javascript
js操作table中tr的顺序实现上移下移一行的效果
2018/11/22 Javascript
原生js实现3D轮播图
2020/03/21 Javascript
Vue 解决路由过渡动画抖动问题(实例详解)
2020/01/05 Javascript
Python中死锁的形成示例及死锁情况的防止
2016/06/14 Python
使用python爬虫实现网络股票信息爬取的demo
2018/01/05 Python
Python实例方法、类方法、静态方法的区别与作用详解
2019/03/25 Python
在keras中获取某一层上的feature map实例
2020/01/24 Python
python 比较字典value的最大值的几种方法
2020/04/17 Python
Python configparser模块操作代码实例
2020/06/08 Python
利用Python实现Json序列化库的方法步骤
2020/09/09 Python
Python中random模块常用方法的使用教程
2020/10/04 Python
CSS3实现可爱的小黄人动画
2016/07/11 HTML / CSS
英国马莎百货官网:Marks & Spencer
2016/07/29 全球购物
宝拉珍选美国官网:Paula’s Choice美国
2018/01/07 全球购物
辞旧迎新演讲稿
2014/09/15 职场文书
生产工厂门卫岗位职责
2014/09/26 职场文书
作风整顿剖析材料
2014/09/30 职场文书
试用期辞职信范文
2015/03/02 职场文书
2015社区个人工作总结范文
2015/05/13 职场文书
小学生禁毒教育心得体会
2016/01/15 职场文书
妇联2016年六一国际儿童节活动总结
2016/04/06 职场文书
[有人@你]你有一封绿色倡议书,请查收!
2019/07/18 职场文书
MySQL系列之二 多实例配置
2021/07/02 MySQL