读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 跨浏览器开发经验总结(五) js 事件
May 19 Javascript
jQuery蓝色风格滑动导航栏代码分享
Aug 19 Javascript
JavaScript操作URL的相关内容集锦
Oct 29 Javascript
JS实现左右无缝轮播图代码
May 01 Javascript
Bootstrap4一次重大更新 几乎涉及每行代码
May 16 Javascript
基于Vue.js的表格分页组件
May 22 Javascript
javascript匀速动画和缓冲动画详解
Oct 20 Javascript
JS实现的添加弹出层并完成锁屏操作示例
Apr 07 Javascript
详解vue项目构建与实战
Jun 27 Javascript
vue.js实现只弹一次弹框
Jan 29 Javascript
详解小程序原生使用ES7 async/await语法
Aug 06 Javascript
vue实例中data使用return包裹的方法
Aug 27 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代码质量36计
2012/09/05 PHP
Zend Studio去除编辑器的语法警告设置方法
2012/10/24 PHP
php中使用addslashes函数报错问题的解决方法
2013/02/06 PHP
PHP+Mysql+jQuery文件下载次数统计实例讲解
2015/10/10 PHP
PHP Header失效的原因分析及解决方法
2016/11/16 PHP
PHP ADODB实现分页功能简单示例
2018/05/25 PHP
js 模拟气泡屏保效果代码
2010/07/10 Javascript
js点击出现悬浮窗效果不使用JQuery插件
2014/01/20 Javascript
JavaScript字符串对象slice方法入门实例(用于字符串截取)
2014/10/16 Javascript
JS实现点击文字对应DIV层不停闪动效果的方法
2015/03/02 Javascript
JavaScript之数组(Array)详解
2015/04/01 Javascript
javascript实现rgb颜色转换成16进制格式
2015/07/10 Javascript
javascript中类的定义方式详解(四种方式)
2015/12/22 Javascript
微信小程序page的生命周期和音频播放及监听实例详解
2017/04/07 Javascript
jQuery复合事件用法示例
2017/06/10 jQuery
微信小程序分页加载的实例代码
2017/07/11 Javascript
vue实现仿淘宝结账页面实例代码
2017/11/08 Javascript
angularJs中跳转到指定的锚点实例($anchorScroll)
2018/08/31 Javascript
nodejs图片处理工具gm用法小结
2018/12/12 NodeJs
详解JavaScript 新语法之Class 的私有属性与私有方法
2019/04/23 Javascript
基于layui轮播图满屏是高度自适应的解决方法
2019/09/16 Javascript
原生javascript单例模式的应用实例分析
2020/02/23 Javascript
Python读写ini文件的方法
2015/05/28 Python
Python 探针的实现原理
2016/04/23 Python
Swift 3.0在集合类数据结构上的一些新变化总结
2016/07/11 Python
使用Python绘制图表大全总结
2017/02/11 Python
python 识别图片中的文字信息方法
2018/05/10 Python
英国设计的甲板鞋和船鞋:Chatham
2018/12/06 全球购物
印尼网上商店:Alfacart.com
2019/03/11 全球购物
STAUD官方网站:洛杉矶独有的闲适风格
2019/04/11 全球购物
2019年Java 最常见的 面试题
2016/10/19 面试题
自荐信包含哪些内容
2013/10/30 职场文书
解除财产保全担保书
2014/05/20 职场文书
学雷锋主题班会教案
2015/08/13 职场文书
2019学校运动会开幕词
2019/05/13 职场文书
dubbo集成zipkin获取Traceid的实现
2021/07/26 Java/Android