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 相关文章推荐
让回调函数 showResponse 也带上参数的代码
Aug 13 Javascript
看了就知道什么是JSON
Dec 09 Javascript
JS格式化数字保留两位小数点示例代码
Oct 15 Javascript
使用jQuery实现验证上传图片的格式与大小
Dec 03 Javascript
Node.js中的process.nextTick使用实例
Jun 25 Javascript
AngularJS基础 ng-options 指令详解
Aug 02 Javascript
简单实现Bootstrap标签页
Aug 09 Javascript
Node.js使用gm拼装sprite图片
Jul 04 Javascript
vue配置多页面的实现方法
May 22 Javascript
Vue头像处理方案小结
Jul 26 Javascript
layer.open 子页面弹出层向父页面传输数据的例子
Sep 26 Javascript
javascript实现左右缓动动画函数
Nov 25 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
让textarea自动调整大小的js代码
2011/04/12 Javascript
js中页面的重新加载(当前页面/上级页面)及frame或iframe元素引用介绍
2013/01/24 Javascript
js获取IP和PcName(IE)在vs中可用
2013/08/02 Javascript
jquery三个关闭弹出层的小示例
2013/11/05 Javascript
原生js实现的贪吃蛇网页版游戏完整实例
2015/05/18 Javascript
jquery的ajax提交form表单的两种方法小结(推荐)
2016/05/25 Javascript
实例讲解JavaScript中的this指向错误解决方法
2016/06/13 Javascript
ECMAScript6快速入手攻略
2016/07/18 Javascript
关于Jquery中的事件绑定总结
2016/10/26 Javascript
JavaScript表单验证的两种实现方法
2017/02/11 Javascript
jQuery+Cookie实现切换皮肤功能【附源码下载】
2018/03/25 jQuery
JS中超越现实的匿名函数用法实例分析
2019/06/21 Javascript
使用Vue-cli3.0创建的项目 如何发布npm包
2019/10/10 Javascript
vue项目打包后请求地址错误/打包后跨域操作
2020/11/04 Javascript
[04:11]2014DOTA2国际邀请赛 CIS遗憾出局梦想不灭
2014/07/09 DOTA
使用Python脚本实现批量网站存活检测遇到问题及解决方法
2016/10/11 Python
Python编程实现粒子群算法(PSO)详解
2017/11/13 Python
python实现图片文件批量重命名
2020/03/23 Python
详解flask入门模板引擎
2018/07/18 Python
Python 经典面试题 21 道【不可错过】
2018/09/21 Python
详解Python二维数组与三维数组切片的方法
2019/07/18 Python
python 实现从高分辨图像上抠取图像块
2020/01/02 Python
python图片剪裁代码(图片按四个点坐标剪裁)
2020/03/10 Python
python数据库编程 Mysql实现通讯录
2020/03/27 Python
韩国休闲女装品牌网站:ANAIS
2016/08/24 全球购物
MAC彩妆澳洲官网:M·A·C AU
2021/01/17 全球购物
CHRONEXT英国:您的首选奢华腕表目的地
2020/03/30 全球购物
校园达人秀策划书
2014/01/12 职场文书
校园活动宣传方案
2014/03/28 职场文书
家长评语怎么写
2014/12/30 职场文书
Nginx中break与last的区别详析
2021/03/31 Servers
JavaScript中MutationObServer监听DOM元素详情
2021/11/27 Javascript
spring cloud eureka 服务启动失败的原因分析及解决方法
2022/03/17 Java/Android
Anaconda安装pytorch和paddle的方法步骤
2022/04/03 Python
vue实现列表垂直无缝滚动
2022/04/08 Vue.js
详解ZABBIX监控ESXI主机的问题
2022/06/21 Servers