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里使用Dom操作Xml
Sep 20 Javascript
分析Node.js connect ECONNREFUSED错误
Apr 09 Javascript
js如何判断不同系统的浏览器类型
Oct 28 Javascript
jquery实现当滑动到一定位置时固定效果
Jun 17 Javascript
JavaScript实现找质数代码分享
Mar 24 Javascript
js+canvas绘制矩形的方法
Jan 28 Javascript
JavaScript正则获取地址栏中参数的方法
Mar 02 Javascript
将angular-ui的分页组件封装成指令的方法详解
May 10 Javascript
微信小程序之选项卡的实现方法
Sep 29 Javascript
使用mpvue搭建一个初始小程序及项目配置方法
Dec 03 Javascript
微信小程序实现watch监听
Jun 04 Javascript
JS前端使用canvas实现物体的点选示例
Aug 05 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
UCenter Home二次开发指南
2009/05/28 PHP
PHP+Mysql+Ajax+JS实现省市区三级联动
2014/05/23 PHP
ThinkPHP自动转义存储富文本编辑器内容导致读取出错的解决方法
2014/08/08 PHP
php上传大文件失败的原因及应对策略
2015/10/20 PHP
Laravel框架路由设置与使用示例
2018/06/12 PHP
摘自启点的main.js
2008/04/20 Javascript
javascript网页关键字高亮代码
2008/07/30 Javascript
JS命名空间的另一种实现
2013/08/09 Javascript
使用jQuery插件创建常规模态窗口登陆效果
2013/08/23 Javascript
javascript中普通函数的使用介绍
2013/12/19 Javascript
jquery中append()与appendto()用法分析
2014/11/14 Javascript
JavaScript获取指定元素位置的方法
2015/04/08 Javascript
跟我学习javascript的最新标准ES6
2015/11/20 Javascript
jQuery实现可以编辑的表格实例详解【附demo源码下载】
2016/07/09 Javascript
canvas实现十二星座星空图
2017/02/14 Javascript
JavaScript 过滤关键字
2017/03/20 Javascript
Angular4学习笔记之实现绑定和分包
2017/08/01 Javascript
MUI 实现侧滑菜单及其主体部分上下滑动的方法
2018/01/25 Javascript
用 js 写一个 js 解释器过程详解
2019/08/02 Javascript
使用Easyui实现查询条件的后端传递并自动刷新表格的两种方法
2019/09/09 Javascript
python爬虫入门教程之糗百图片爬虫代码分享
2014/09/02 Python
简单介绍Python中的struct模块
2015/04/28 Python
Centos 升级到python3后pip 无法使用的解决方法
2018/06/12 Python
Python安装pycurl失败的解决方法
2018/10/15 Python
Python中查看变量的类型内存地址所占字节的大小
2019/06/26 Python
Python3.7+tkinter实现查询界面功能
2019/12/24 Python
Python之字典对象的几种创建方法
2020/09/30 Python
python 实现百度网盘非会员上传超过500个文件的方法
2021/01/07 Python
Python3利用scapy局域网实现自动多线程arp扫描功能
2021/01/21 Python
使用CSS3制作倾斜导航条和毛玻璃效果
2017/09/12 HTML / CSS
使用HTML和CSS3绘制基本卡通图案的示例分享
2015/11/06 HTML / CSS
法国女性内衣购物网站:Glamuse
2019/05/13 全球购物
C#笔试题
2015/07/14 面试题
迎新晚会主持词开场白
2015/05/28 职场文书
2015党建工作简报
2015/07/21 职场文书
Python数据类型最全知识总结
2021/05/31 Python