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 相关文章推荐
List the Stored Procedures in a SQL Server database
Jun 20 Javascript
JavaScript表达式:URL 协议介绍
Mar 10 Javascript
js防止DIV布局滚动时闪动的解决方法
Oct 30 Javascript
nw.js实现类似微信的聊天软件
Mar 16 Javascript
js立即执行函数: (function ( ){})( ) 与 (function ( ){}( )) 有什么区别?
Nov 18 Javascript
浅析Bootstrip的select控件绑定数据的问题
May 10 Javascript
JavaScript原生数组Array常用方法
Apr 06 Javascript
Linux系统中利用node.js提取Word(doc/docx)及PDF文本的内容
Jun 17 Javascript
详解Node.js读写中文内容文件操作
Oct 10 Javascript
vue项目中使用bpmn为节点添加颜色的方法
Apr 30 Javascript
从Node.js事件触发器到Vue自定义事件的深入讲解
Jun 26 Javascript
vue实现路由懒加载的3种方法示例
Sep 01 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
在PWS上安装PHP4.0正式版
2006/10/09 PHP
php下载远程文件类(支持断点续传)
2008/11/14 PHP
PHP记录页面停留时间的方法
2016/03/30 PHP
phpmailer简单发送邮件的方法(附phpmailer源码下载)
2016/06/13 PHP
使用IE6看老赵的博客 jQuery初探
2010/01/17 Javascript
extjs tabpanel限制选项卡数量实现思路及代码
2013/04/02 Javascript
nodejs读取memcache示例分享
2014/01/02 NodeJs
Jquery响应回车键直接提交表单操作代码
2014/07/25 Javascript
JSONP之我见
2015/03/24 Javascript
jQuery实现ToolTip元素定位显示功能示例
2016/11/23 Javascript
原生js jquery ajax请求以及jsonp的调用方法
2017/08/04 jQuery
ajax请求data遇到的问题分析
2018/01/18 Javascript
vue2.0模拟锚点的实例
2018/03/14 Javascript
如何更好的编写js async函数
2018/05/13 Javascript
Vue组件为什么data必须是一个函数
2020/06/11 Javascript
解决vue组件销毁之后计时器继续执行的问题
2020/07/21 Javascript
Python使用scrapy抓取网站sitemap信息的方法
2015/04/08 Python
Python+matplotlib实现计算两个信号的交叉谱密度实例
2018/01/08 Python
python中数据爬虫requests库使用方法详解
2018/02/11 Python
在Python中字典根据多项规则排序的方法
2019/01/21 Python
谈一谈基于python的面向对象编程基础
2019/05/21 Python
python SocketServer源码深入解读
2019/09/17 Python
python selenium循环登陆网站的实现
2019/11/04 Python
Pycharm创建项目时如何自动添加头部信息
2019/11/14 Python
python画环形图的方法
2020/03/25 Python
keras实现基于孪生网络的图片相似度计算方式
2020/06/11 Python
Bailey帽子官方商店:Bailey Hats
2018/09/25 全球购物
幼儿园义卖活动方案
2014/01/17 职场文书
社区学雷锋活动策划方案
2014/01/30 职场文书
初一家长会邀请函
2014/01/31 职场文书
致跳远运动员广播稿
2014/02/11 职场文书
三分钟英语演讲稿
2014/04/24 职场文书
普通话宣传标语
2014/06/26 职场文书
2015年度培训工作总结范文
2015/04/02 职场文书
Python 快速验证代理IP是否有效的方法实现
2021/07/15 Python
我的收音机情缘
2022/04/05 无线电