浅析jQuery的链式调用之each函数


Posted in Javascript onDecember 03, 2010

话说回来,虽然jQuery让学习前端技术的越来越多了起来,(本人就是因为学校图书馆偶然间遇到了一本jQuery基础教程(二)开始想深入的学习前端技术),关于jQuery的博文甚至多于javascript,它让编程的门槛大大的降低了,但是它隐藏了太多细节了,形如$('#id').append('<p>xxx</p>').clone().appendTo(x).end().css(...)................这样操作的模式已经很难找到常规javascript的影子。浏览器的差异仿佛一去就不见了踪影,我不认为大部分都能在这安逸的环境再重新回到考虑javascript如何在不同浏览器能表现一致等问题,是福是祸真的很难说。
接下来言归正传.....说正经的
由于$()函数返回的是一个包裹了原生dom对象数组的对象,并且在此对象原型上扩展的函数都是为了操作原生的dom对象,所以少不了循环遍历的操作,熟悉jquery库的人都知道有个jQuery.each()函数 ,大部分的涉及jquery对象的函数都会用到这个函数: 简单的实现应该是形如这样:
(再次重申,只是简单的实现原理,不要考虑具体的功能性问题)

if (!window['$']) 
window['$'] = window['jQuery']; 
/*这里以上区域为上一篇文章的闭包内的内容 
* 定义jQuery.each 根据传入对象来执行操作 
* @param {Object} obj 
* @param {Object} func 
*简单起见我只考虑了数组以及jQuery对象两种情况,跟上一篇一样,原理应该是一致的 
*/ 
window['jQuery']['each']=function(obj,func){ 
if(obj.constructor==Array){ 
for(var i=0;i<obj.length;i++){ 
func.call(obj[i],i,obj[i]);//可以看到传入的func 应该是形如function(i,item) i代表遍历到的下标,item则代表在数组中遍历到的对象 
} 
}else if(obj.elements&&obj.elements.constructor==Array){//这里采用了传说的鸭子法则,而不是判定它是不是jQuery的实例 只要你有Array类型的elements我就对你进行操作 
for(var i=0;i<obj.elements.length;i++){ 
func.call(obj.elements[i],i,obj.elements[i]);//可以看到传入的func 应该是形如function(i,item) i代表遍历到的下标,item则代表在数组中遍历到的对象 
} 
}else{ 
return null; 
} 
}

在这个函数的基础之上可以开始扩充_jQuery的prototype了;首先就是先写一个包装器对象可以直接调用的方法each:(这个并不是重复),然后通过调用这个each函数可以完成对对象数组的遍历,
比如:
//写在闭包内 注意将昨天命名冲突了的jQuery构造函数名称改为_jQuery 
_jQuery.prototype = { 
each: function(func){ 
jQuery.each(this, func); 
return this; 
}, 
attr: function(key, value){ 
//示例定义这个set与get于一身的操作属性的函数 
if (arguments.length == 0) { 
return null; 
} 
else 
if (arguments.length == 1) { 
return this.elements[0].getAttribute(key); 
} 
else if(arguments.length == 2){ 
this.each(function(i, item){ 
//这里可以看到重新定义each方法的好处一:精简代码 ,二:在内部函数中this仍然是指向调用的包装器对象而不是window 
item.setAttribute(key, value); 
}) 
} 
} 
/* 
* 这里可以开始引入其他方法 
*/ 
}

接下来做几个简单的测试:(还是上一篇的测试html

输入:

   var k= $('#header');
                  consoles.write(k.attr('title','test title!').attr('title'));     //链式调用 

  输出:   

                   test title!

依此类推,依靠each方法可以有效的扩充包装器的方法。

之前说的影响到jQuery的链式调用的要点有三点,事实事后一想完全不是那么简单,jQuery内部代码的维护感觉并不比有些库好,虽然至少在操作上来讲使用起来非常顺手(当然只是针对一些小的操作,大的项目一时也无法接触到,也不好跟着一些大大人云亦云). 不过就算仅仅从遍历操作来看, 也可以看到其实这个库只能依托细化的插件,扩充下去只会显得臃肿不堪。

注:如果有仔细剖析了jquery源码的人肯定会对我如此拙劣的所谓的实现嗤之以鼻,我的确只是看了几本比如javascript dom高级程序设计 以及javascript 高级程序设计 设计模式等好书之后有感而发而已,可能跟具体的jquery的实现有很大的落差,可以的话希望可以指正一下。

Javascript 相关文章推荐
Javascript调用XML制作连动下拉列表框
Jun 25 Javascript
jQuery之ajax技术的详细介绍
Jun 19 Javascript
javascript实现根据时间段显示问候语的方法
Jun 18 Javascript
Bootstrap下拉菜单效果实例代码分享
Jun 30 Javascript
AngularJS表格详解及示例代码
Aug 17 Javascript
Flask中获取小程序Request数据的两种方法
May 12 Javascript
微信小程序之几种常见的弹框提示信息实现详解
Jul 11 Javascript
JS常用排序方法实例代码解析
Mar 03 Javascript
解决父组件将子组件作为弹窗调用只执行一次created的问题
Jul 24 Javascript
vue addRoutes路由动态加载操作
Aug 04 Javascript
js实现三角形粒子运动
Sep 22 Javascript
详解TS数字分隔符和更严格的类属性检查
May 06 Javascript
jQuery的链式调用浅析
Dec 03 #Javascript
加速IE的Javascript document输出的方法
Dec 02 #Javascript
关于Ext中form移除textfield方法:hide(),setVisible(false),remove()
Dec 02 #Javascript
javascript学习之闭包分析
Dec 02 #Javascript
JavaScript OOP面向对象介绍
Dec 02 #Javascript
JavaScript 字符串处理函数使用小结
Dec 02 #Javascript
改写一个简单的菜单 弹性大小
Dec 02 #Javascript
You might like
PHP删除数组中特定元素的两种方法
2013/07/02 PHP
CI框架的安全性分析
2016/05/18 PHP
php使用gearman进行任务分发操作实例详解
2020/02/26 PHP
PHP array_reverse() 函数原理及实例解析
2020/07/14 PHP
网络之美 JavaScript中Get和Set访问器的实现代码
2010/09/19 Javascript
JS/FLASH实现复制代码到剪贴板(兼容所有浏览器)
2013/05/27 Javascript
javascript实现切换td中的值
2014/12/05 Javascript
JS实现一个按钮的方法
2015/02/05 Javascript
javascript生成img标签的3种实现方法(对象、方法、html)
2015/12/25 Javascript
JS继承之借用构造函数继承和组合继承
2016/09/07 Javascript
用React-Native+Mobx做一个迷你水果商城APP(附源码)
2017/12/25 Javascript
JavaScript数组,JSON对象实现动态添加、修改、删除功能示例
2018/05/26 Javascript
Vue.js实现的计算器功能完整示例
2018/07/11 Javascript
微信小程序当前时间时段选择器插件使用方法详解
2018/12/28 Javascript
史上最为详细的javascript继承(推荐)
2019/05/18 Javascript
Vue页面切换和a链接的本质区别详解
2019/11/12 Javascript
vue各种事件监听实例(小结)
2020/06/24 Javascript
[42:06]2019国际邀请赛全明星赛 8.23
2019/09/05 DOTA
Anaconda2 5.2.0安装使用图文教程
2018/09/19 Python
pthon贪吃蛇游戏详细代码
2019/01/27 Python
你应该知道的Python3.6、3.7、3.8新特性小结
2020/05/12 Python
Python中socket网络通信是干嘛的
2020/05/27 Python
python爬取抖音视频的实例分析
2021/01/19 Python
Python开发.exe小工具的详细步骤
2021/01/27 Python
乌克兰在线商店的价格比较:Price.ua
2019/07/26 全球购物
瑞士男士时尚网上商店:Babista
2020/05/14 全球购物
2019年分享net面试的经历和题目
2016/08/07 面试题
什么是ARP(Address Resolution Protocol)地址解析协议
2013/10/31 面试题
C#软件工程师英语面试题
2015/06/07 面试题
小学生个人先进事迹材料
2014/05/08 职场文书
大型活动组织方案
2014/05/10 职场文书
2014国庆节商场促销活动策划方案
2014/09/16 职场文书
大学毕业论文致谢词
2015/05/14 职场文书
初中运动会前导词
2015/07/20 职场文书
导游词之无锡唐城
2019/12/12 职场文书
win10+RTX3050ti+TensorFlow+cudn+cudnn配置深度学习环境的方法
2022/06/25 Servers