读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移动div层-javascript 拖动层
Mar 22 Javascript
Javascript 键盘keyCode键码值表
Dec 24 Javascript
基于javascript实现的搜索时自动提示功能
Dec 26 Javascript
JavaScript中DOM详解
Apr 13 Javascript
javascript动画之模拟拖拽效果篇
Sep 26 Javascript
boostrapTable的refresh和refreshOptions区别浅析
Jan 22 Javascript
Axios学习笔记之使用方法教程
Jul 21 Javascript
浅谈webpack编译vue项目生成的代码探索
Dec 11 Javascript
vue中子组件向父组件传递数据的实例代码(实现加减功能)
Apr 20 Javascript
Vue2.0中三种常用传值方式(父传子、子传父、非父子组件传值)
Aug 16 Javascript
JS实现的类似微信聊天效果示例
Jan 29 Javascript
nuxt+axios实现打包后动态修改请求地址的方法
Apr 22 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
老司机传授Ubuntu下Apache+PHP+MySQL环境搭建攻略
2016/03/20 PHP
微信 开发生成带参数的二维码的实例
2016/11/23 PHP
PHP删除数组中指定值的元素常用方法实例分析【4种方法】
2018/08/21 PHP
判断文件是否正在被使用的JS代码
2013/12/21 Javascript
JavaScript中对象property的删除方法介绍
2014/12/30 Javascript
windows下安装nodejs及框架express
2015/08/07 NodeJs
Jquery 整理元素选取、常用方法一览表
2016/11/26 Javascript
bootstrap使用validate实现简单校验功能
2016/12/02 Javascript
简单谈谈Javascript函数中的arguments
2017/02/09 Javascript
javascript高级模块化require.js的具体使用方法
2017/10/31 Javascript
js实现json数组分组合并操作示例
2019/02/12 Javascript
ES6入门教程之let、const的使用方法
2019/04/13 Javascript
package.json配置文件构成详解
2019/08/27 Javascript
vue下canvas裁剪图片实例讲解
2020/04/16 Javascript
[02:25]DOTA2英雄基础教程 熊战士
2014/01/03 DOTA
Python的爬虫程序编写框架Scrapy入门学习教程
2016/07/02 Python
Python自动化测试ConfigParser模块读写配置文件
2016/08/15 Python
详解python中的json的基本使用方法
2016/12/21 Python
pycharm下打开、执行并调试scrapy爬虫程序的方法
2017/11/29 Python
pyqt5实现登录界面的模板
2020/05/30 Python
Python基于机器学习方法实现的电影推荐系统实例详解
2019/06/25 Python
PyCharm中如何直接使用Anaconda已安装的库
2020/05/28 Python
Keras 数据增强ImageDataGenerator多输入多输出实例
2020/07/03 Python
HTML5 canvas绘制的玫瑰花效果
2014/05/29 HTML / CSS
英国泰坦旅游网站:全球陪同游览,邮轮和铁路旅行
2016/11/29 全球购物
官方授权图形T恤和服装:Fifth Sun
2019/06/12 全球购物
什么是表空间(tablespace)和系统表空间(System tablespace)
2013/02/25 面试题
汽车队司机先进事迹材料
2014/02/01 职场文书
交通事故私了协议书
2014/04/16 职场文书
征用土地赔偿协议书
2014/09/26 职场文书
预备党员考察表党小组意见
2015/06/01 职场文书
Java练习之潜艇小游戏的实现
2022/03/16 Java/Android
一文搞懂Redis中String数据类型
2022/04/03 Redis
Android studio 简单计算器的编写
2022/05/20 Java/Android
Java 多线程并发FutureTask
2022/06/28 Java/Android
Python 读取千万级数据自动写入 MySQL 数据库
2022/06/28 Python