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实现 在光标处插入指定内容
May 25 Javascript
提高网站信任度的技巧
Oct 17 Javascript
Js-$.extend扩展方法使方法参数更灵活
Jan 15 Javascript
在页面上用action传递参数到后台出现乱码的解决方法
Dec 31 Javascript
jQuery检测滚动条是否到达底部
Dec 15 Javascript
在JavaScript中call()与apply()区别
Jan 22 Javascript
浅谈JSON.stringify()和JOSN.parse()方法的不同
Aug 29 Javascript
微信小程序-消息提示框实例
Nov 24 Javascript
Js利用Canvas实现图片压缩功能
Sep 13 Javascript
element-ui 中的table的列隐藏问题解决
Aug 24 Javascript
JavaScript forEach中return失效问题解决方案
Jun 01 Javascript
通过JS判断网页是否为手机打开
Oct 28 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 Array交叉表实现代码
2010/08/05 PHP
php微信公众平台开发之微信群发信息
2016/09/13 PHP
PHP实现的mysql主从数据库状态检测功能示例
2017/07/20 PHP
PHP实现表单提交数据的验证处理功能【防SQL注入和XSS攻击等】
2017/07/21 PHP
thinkphp5 URL和路由的功能详解与实例
2017/12/26 PHP
jquery和javascript中如何将一元素的内容赋给另一元素
2014/01/09 Javascript
使用jquery解析XML示例代码
2014/09/05 Javascript
正则表达式,替换所有HTML标签的简单实例
2016/11/28 Javascript
利用jquery实现验证输入的是否是数字、小数,包含保留几位小数
2016/12/07 Javascript
Angular将填入表单的数据渲染到表格的方法
2017/09/22 Javascript
快速解决select2在bootstrap模态框中下拉框隐藏的问题
2018/08/10 Javascript
js实现继承的方法及优缺点总结
2019/05/08 Javascript
小程序实现按下录音松开识别语音
2019/11/22 Javascript
解决vue组件销毁之后计时器继续执行的问题
2020/07/21 Javascript
JavaScript动态生成表格的示例
2020/11/02 Javascript
Python内置函数dir详解
2015/04/14 Python
在Python中使用mongoengine操作MongoDB教程
2015/04/24 Python
用Python将mysql数据导出成json的方法
2018/08/21 Python
python 对key为时间的dict排序方法
2018/10/17 Python
python GUI库图形界面开发之PyQt5 Qt Designer工具(Qt设计师)详细使用方法及Designer ui文件转py文件方法
2020/02/26 Python
基于python检查矩阵计算结果
2020/05/21 Python
浅谈tensorflow中dataset.shuffle和dataset.batch dataset.repeat注意点
2020/06/08 Python
利用python清除移动硬盘中的临时文件
2020/10/28 Python
python输出国际象棋棋盘的实例分享
2020/11/26 Python
在 Python 中使用 7zip 备份文件的操作
2020/12/11 Python
解决Python import .pyd 可能遇到路径的问题
2021/03/04 Python
Agoda台湾官网:国内外订房2折起
2018/03/20 全球购物
什么是View State?
2013/01/27 面试题
感恩节红领巾广播稿
2014/02/11 职场文书
整顿机关作风心得体会
2014/09/10 职场文书
2014年终工作总结范本
2014/12/15 职场文书
董事长岗位职责
2015/02/13 职场文书
加薪申请报告范本
2015/05/15 职场文书
2015年团委副书记工作总结
2015/07/23 职场文书
执行力心得体会范文
2016/01/11 职场文书
深入解析MySQL索引数据结构
2021/10/16 MySQL