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链式操作如何实现以及为什么要用链式操作
Jan 17 Javascript
jquery图片切换实例分析
Apr 15 Javascript
Grunt入门教程(自动任务运行器)
Aug 06 Javascript
基于Angularjs实现分页功能
May 30 Javascript
js删除Array数组中指定元素的两种方法
Aug 03 Javascript
js实现各种复制到剪贴板的方法(分享)
Oct 27 Javascript
3种不同的ContextMenu右键菜单实现代码
Nov 03 Javascript
jQuery遮罩层实例讲解
May 11 jQuery
基于vue通用表单解决方案的思考与分析
Mar 16 Javascript
微信小程序Flex布局用法深入浅出分析
Apr 25 Javascript
vue-cli在 history模式下的配置详解
Nov 26 Javascript
html5以及jQuery实现本地图片上传前的预览代码实例讲解
Mar 01 jQuery
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随机获取金山词霸每日一句的方法
2015/07/09 PHP
php使用CURL模拟GET与POST向微信接口提交及获取数据的方法
2016/09/23 PHP
Zend Framework数据库操作技巧总结
2017/02/18 PHP
在thinkphp5.0路径中实现去除index.php的方式
2019/10/16 PHP
JavaScript 实现简单的倒计时弹窗DEMO附图
2014/03/05 Javascript
jQuery级联操作绑定事件实例
2014/09/02 Javascript
JavaScript使用slice函数获取数组部分元素的方法
2015/04/06 Javascript
jquery插件uploadify实现带进度条的文件批量上传
2015/12/13 Javascript
Bootstrap Paginator分页插件与ajax相结合实现动态无刷新分页效果
2016/05/27 Javascript
JQuery对ASP.NET MVC数据进行更新删除
2016/07/13 Javascript
AngularJS自定义控件实例详解
2016/12/13 Javascript
JS中正则表达式要注意lastIndex属性
2017/08/08 Javascript
vue 巧用过渡效果(小结)
2018/09/22 Javascript
js隐式转换的知识实例讲解
2018/09/28 Javascript
如何使用puppet替换文件中的string
2018/12/06 Javascript
浅谈Node框架接入ELK实践总结
2019/02/22 Javascript
layui-table表复选框勾选的所有行数据获取的例子
2019/09/13 Javascript
JS Web Flex弹性盒子模型代码实例
2020/03/10 Javascript
python随机生成指定长度密码的方法
2015/04/04 Python
python 基础教程之Map使用方法
2017/01/17 Python
Python 专题六 局部变量、全局变量global、导入模块变量
2017/03/20 Python
Python计算斗牛游戏概率算法实例分析
2017/09/26 Python
将python文件打包成EXE应用程序的方法
2019/05/22 Python
Python matplotlib可视化实例解析
2020/06/01 Python
tensorflow图像裁剪进行数据增强操作
2020/06/30 Python
python3爬虫中多线程的优势总结
2020/11/24 Python
自荐信写法介绍
2014/01/25 职场文书
会计专业个人自我鉴定
2014/03/21 职场文书
本科生求职信
2014/06/17 职场文书
公司领导班子群众路线四风问题对照检查材料
2014/10/02 职场文书
全陪导游词
2015/02/04 职场文书
骨干教师个人总结
2015/02/11 职场文书
驻村工作简报
2015/07/20 职场文书
2015初中政教处工作总结
2015/07/21 职场文书
卫生主题班会
2015/08/14 职场文书
Nginx 过滤静态资源文件的访问日志的实现
2021/03/31 Servers