jQuery中的pushStack实现原理和应用实例


Posted in Javascript onFebruary 03, 2015

pushStack是jQuery内核中一个非常重要的函数,它是如此重要,以至于许多jQuery内部函数中都频繁用到它。平常情况下,虽然很少用到它, 但是掌握这个函数,不仅有利于理解jQuery的运行原理,还方便我们做更加高级的jQuery操作。

顾名思义,pushStack是入栈, 栈作为一种数据结构,是一种只能在一端进行插入和删除操作的特殊线性表。数据入栈时,类似与我们进电梯,后进而先出, 如下图:

jQuery中的pushStack实现原理和应用实例

jQuery中的栈其实并不是真正的栈,而是给jQuery对象附加一个属性,指向当前对象的上一个对象, 通过end方法就能返回上一个元素。如下:

<span>1</span>
<span>2</span>
<span>3</span>
<script>
$('span').eq(0).css('fontSize','20px').end().fadeOut(2000);
</script>

上面的代码会使第一个span的字体大小为20px,并让所有span在2秒钟之内fadaout。

pushStack属于jQuery的实例方法,通过jQuery对象调用,如通过$().pushStack(document.getElementsByTagName(‘div')).css(‘background','blue')把所有div的背景都设置为蓝色。那么pushStack的原理是什么,为什么传入的DOM对象可以用css方法操作呢?先来看一下jQuery中pushStack的源码:

pushStack: function( elems ) {
 // Build a new jQuery matched element set
 var ret = jQuery.merge( this.constructor(), elems );
 // Add the old object onto the stack (as a reference)
 ret.prevObject = this;
 ret.context = this.context;
 // Return the newly-formed element set
 return ret;
}
//jQuery.merge
merge: function( first, second ) {
 var l = second.length,
 i = first.length,
 j = 0;
 if ( typeof l === "number" ) {
 for ( ; j < l; j++ ) {
  first[ i++ ] = second[ j ];
 }
 } else {
 while ( second[j] !== undefined ) {
  first[ i++ ] = second[ j++ ];
 }
 }
 first.length = i;
 return first;
}

pushStack的实现比较简单,主要涉及到jQuery的静态方法merge, 这个方法用来合并对象, 设计思路是在第一个对象的基础上,把第二个对象的属性(0至n)附加上去, 理解这一点很重要。再回到pushStack这个函数,首先定义一个局部变量ret存储合并对象,然后给这个对象存储prevObject和context属性,最后返回合并之后的ret对象。这里有几点需要注意:
1, this.constructor 就是jQuery的构造函数init,所以this.constructor()返回一个jQuery对象.
2, 由于jQuery merge函数返回的对象是第二个函数附加到第一个上面,所以ret也是一个jQuery对象,这里可以解释为什么pushStack出入的DOM对象也可以用CSS方法进行操作。
3, 返回的对象的prevObject属性指向上一个对象,所以可以通过这个属性找到栈的上一个对象.

Javascript 相关文章推荐
JS对外部文件的加载及对IFRMAME的加载的实现,当加载完成后,指定指向方法(方法回调)
Jul 04 Javascript
js查错流程归纳
May 04 Javascript
[JSF]使用DataModel处理表行事件的实例代码
Aug 05 Javascript
jquery自定义类似$.ajax()的方法实现代码
Aug 13 Javascript
JS根据生日算年龄的方法
May 05 Javascript
JavaScript的jQuery库中ready方法的学习教程
Aug 14 Javascript
jQuery easyui刷新当前tabs的方法
Sep 23 Javascript
ExtJS 4.2 Grid组件单元格合并的方法
Oct 12 Javascript
Javascript 函数的四种调用模式
Nov 05 Javascript
angular4 如何在全局设置路由跳转动画的方法
Aug 30 Javascript
8个有意思的JavaScript面试题
Jul 30 Javascript
从源码角度来回答keep-alive组件的缓存原理
Jan 18 Javascript
JavaScript闭包详解
Feb 02 #Javascript
js实现浏览器窗口大小被改变时触发事件的方法
Feb 02 #Javascript
javascript的switch用法注意事项分析
Feb 02 #Javascript
jQuery实现长按按钮触发事件的方法
Feb 02 #Javascript
jQuery实现跟随鼠标运动图层效果的方法
Feb 02 #Javascript
JavaScript针对网页节点的增删改查用法实例
Feb 02 #Javascript
jQuery通过控制节点实现仅在前台通过get方法完成参数传递
Feb 02 #Javascript
You might like
隐藏X-Space个人空间下方版权方法隐藏X-Space个人空间标题隐藏X-Space个人空间管理版权方法
2007/02/22 PHP
YII Framework框架教程之缓存用法详解
2016/03/14 PHP
基于PHP生成简单的验证码
2016/06/01 PHP
PHP pthreads v3下worker和pool的使用方法示例
2020/02/21 PHP
javascript读取RSS数据
2007/01/20 Javascript
js关闭当前页面(窗口)的几种方式总结
2013/03/05 Javascript
jquery动态加载select下拉框示例代码
2013/12/10 Javascript
node.js中使用socket.io制作命名空间
2014/12/15 Javascript
javascript图片预加载完整实例
2015/12/10 Javascript
jQuery对checkbox 复选框的全选全不选反选的操作
2016/08/09 Javascript
JavaScript字符集编码与解码详谈
2017/02/02 Javascript
js实现倒计时效果(小于10补零)
2017/03/08 Javascript
微信小程序实现全局搜索代码高亮的示例
2018/03/30 Javascript
解决cordova+vue 项目打包成APK应用遇到的问题
2019/05/10 Javascript
Angular8 Http拦截器简单使用教程
2019/08/20 Javascript
微信小程序跨页面传递data数据方法解析
2019/12/13 Javascript
修改NPM全局模式的默认安装路径的方法
2020/12/15 Javascript
Python中使用Boolean操作符做真值测试实例
2015/01/30 Python
Python使用matplotlib和pandas实现的画图操作【经典示例】
2018/06/13 Python
利用python对Excel中的特定数据提取并写入新表的方法
2018/06/14 Python
python hbase读取数据发送kafka的方法
2018/12/27 Python
python获取服务器响应cookie的实例
2018/12/28 Python
20行python代码实现人脸识别
2019/05/05 Python
使用Python的OpenCV模块识别滑动验证码的缺口(推荐)
2019/05/10 Python
python 利用turtle模块画出没有角的方格
2019/11/23 Python
Django缓存Cache使用详解
2020/11/30 Python
美国批发供应商:Kole Imports
2019/04/10 全球购物
运动会入场解说词300字
2014/01/25 职场文书
学历公证委托书
2014/04/09 职场文书
2014年安全生产目标责任书
2014/07/23 职场文书
秦始皇兵马俑导游词
2015/02/02 职场文书
博士论文答辩开场白
2015/06/01 职场文书
2015团员个人年度总结
2015/11/24 职场文书
导游词之塘栖古镇
2019/12/04 职场文书
如何在python中实现ECDSA你知道吗
2021/11/23 Python
java高级用法JNA强大的Memory和Pointer
2022/04/19 Java/Android