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 相关文章推荐
jQuery之选择组件的深入解析
Jun 19 Javascript
使用insertAfter()方法在现有元素后添加一个新元素
May 28 Javascript
AngularJS中的过滤器使用详解
Jun 16 Javascript
jQuery+AJAX实现无刷新下拉加载更多
Jul 03 Javascript
JS实现页面载入时随机显示图片效果
Sep 07 Javascript
vue调用高德地图实例代码
Apr 28 Javascript
JS判断一个数是否是水仙花数
Jun 11 Javascript
vue.js移动端app之上拉加载以及下拉刷新实战
Sep 11 Javascript
JS实现的文字间歇循环滚动效果完整示例
Feb 13 Javascript
Vue CLI 2.x搭建vue(目录最全分析)
Feb 27 Javascript
JavaScript跳出循环的三种方法(break, return, continue)
Jul 30 Javascript
js+css实现全屏侧边栏
Jun 16 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
PHP分页显示制作详细讲解
2006/10/09 PHP
yii2实现分页,带搜索的分页功能示例
2017/01/07 PHP
PHP实现APP微信支付的实例讲解
2018/02/10 PHP
PHP中有关长整数的一些操作教程
2019/09/11 PHP
利用window.name实现windowStorage代码分享
2014/01/02 Javascript
使用GruntJS构建Web程序之Tasks(任务)篇
2014/06/06 Javascript
Node.js和MongoDB实现简单日志分析系统
2015/04/25 Javascript
详解JavaScript中的异常处理方法
2015/06/16 Javascript
jquery特效 点击展示与隐藏全文
2015/12/09 Javascript
jQuery Mobile 触摸事件实例
2016/06/04 Javascript
bootstrap学习笔记之初识bootstrap
2016/06/21 Javascript
微信小程序实现天气预报功能
2018/07/18 Javascript
JQuery实现简单的复选框树形结构图示例【附源码下载】
2019/07/16 jQuery
vue学习笔记之作用域插槽实例分析
2020/02/01 Javascript
js中!和!!的区别与用法
2020/05/09 Javascript
OpenLayers实现图层切换控件
2020/09/25 Javascript
[02:08]2014DOTA2国际邀请赛 430专访:力争取得小组前二
2014/07/11 DOTA
python调用java的Webservice示例
2014/03/10 Python
python实现比较文件内容异同
2018/06/22 Python
对Python+opencv将图片生成视频的实例详解
2019/01/08 Python
使用pycharm在本地开发并实时同步到服务器
2019/08/02 Python
使用Python进行中文繁简转换的实现代码
2019/10/18 Python
Python使用requests xpath 并开启多线程爬取西刺代理ip实例
2020/03/06 Python
python类共享变量操作
2020/09/03 Python
HTML5 画布canvas使用方法
2016/03/18 HTML / CSS
Html5之title吸顶功能
2018/06/04 HTML / CSS
HTML5拖拽文件上传的示例代码
2021/03/04 HTML / CSS
Giglio俄罗斯奢侈品购物网:男士、女士、儿童高级时装
2018/07/27 全球购物
三陽商会官方网站:Sanyo iStore
2019/05/15 全球购物
工商管理应届生求职信
2013/10/07 职场文书
培训自我鉴定
2014/01/31 职场文书
2015年银行大堂经理工作总结
2015/04/24 职场文书
给学校的建议书400字
2015/09/14 职场文书
Promise面试题详解之控制并发
2021/05/14 面试题
nginx中proxy_pass各种用法详解
2021/11/07 Servers
SQL SERVER中的流程控制语句
2022/05/25 SQL Server