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 相关文章推荐
JavaScript中的Document文档对象
Jan 16 Javascript
JavaScript 判断浏览器类型及版本
Feb 21 Javascript
jQuery中add实现同时选择两个id对象
Oct 22 Javascript
禁用键盘上的(全局)指定键兼容iE、Chrome、火狐
May 14 Javascript
前端必备插件之纯原生JS的瀑布流插件Macy.js
Nov 22 Javascript
css和js实现弹出登录居中界面完整代码
Nov 26 Javascript
使用Vue开发一个实时性时间转换指令
Jan 17 Javascript
Node.js 使用request模块下载文件的实例
Sep 05 Javascript
JavaScript时间与时间戳的转换操作实例分析
Dec 07 Javascript
JS实现checkbox互斥(单选)功能示例
May 04 Javascript
JS利用prototype给类添加方法操作详解
Jun 21 Javascript
JavaScript设计模式之策略模式实现原理详解
May 29 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
ThinkPHP3.1之D方法实例详解
2014/06/20 PHP
使用PHP实现微信摇一摇周边红包
2016/01/04 PHP
JavaScript使用prototype定义对象类型
2007/02/07 Javascript
JavaScript入门教程 Cookies
2009/01/31 Javascript
基于jquery实现一张图片点击鼠标放大再点缩小
2013/09/29 Javascript
js脚本分页代码分享(7种样式)
2015/08/19 Javascript
jQuery实现的点赞随机数字显示动画效果(附在线演示与demo源码下载)
2015/12/31 Javascript
WordPress中利用AJAX异步获取评论用户头像的方法
2016/01/08 Javascript
js实现的万能flv网页播放器代码
2016/04/30 Javascript
Jquery $when done then的用法详解
2016/05/20 Javascript
jQuery实现定位滚动条位置
2016/08/05 Javascript
Windows下快速搭建NodeJS本地服务器的步骤
2017/08/09 NodeJs
fetch 如何实现请求数据
2018/12/20 Javascript
element表格翻页第2页从1开始编号(后端从0开始分页)
2019/12/10 Javascript
关于Node.js中频繁修改代码重启服务器的问题
2020/10/15 Javascript
解决pycharm双击但是无法打开的情况
2020/10/31 Javascript
[01:25]2014DOTA2国际邀请赛 zhou分析LGD比赛情况
2014/07/14 DOTA
用Python制作在地图上模拟瘟疫扩散的Gif图
2015/03/31 Python
Pycharm如何打断点的方法步骤
2019/06/13 Python
PyQt5实现QLineEdit添加clicked信号的方法
2019/06/25 Python
pip install python 快速安装模块的教程图解
2019/10/08 Python
PyQt5实现登录页面
2020/05/30 Python
使用python库xlsxwriter库来输出各种xlsx文件的示例
2020/09/01 Python
Python利用Pillow(PIL)库实现验证码图片的全过程
2020/10/04 Python
如何使用python-opencv批量生成带噪点噪线的数字验证码
2020/12/21 Python
Pam & Gela官网:美国性感前卫女装品牌
2018/07/19 全球购物
Ibatis的核心配置文件都有什么
2014/09/08 面试题
医院辞职信范文
2014/01/17 职场文书
卫校毕业生个人自我鉴定
2014/04/28 职场文书
禁止酒驾标语
2014/06/25 职场文书
乒乓球比赛通知
2015/04/27 职场文书
大学生青年志愿者活动总结
2015/05/06 职场文书
小学生手册家长意见
2015/06/03 职场文书
入队仪式主持词
2015/07/04 职场文书
2016领导干部廉洁自律心得体会
2016/01/13 职场文书
导游词之岳阳楼
2019/09/25 职场文书