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玩转游戏物理(一)运动学模拟与粒子系统
Jun 19 Javascript
Js判断参数(String,Array,Object)是否为undefined或者值为空
Nov 04 Javascript
Javascript设置对象的ReadOnly属性(示例代码)
Dec 25 Javascript
简单分析javascript面向对象与原型
May 21 Javascript
jQuery Easyui datagrid/treegrid 清空数据
Jul 09 Javascript
Node.js制作简单聊天室
Jan 12 Javascript
老生常谈js中的MVC
Jul 25 Javascript
基于Vue实现可以拖拽的树形表格实例详解
Oct 18 Javascript
vue-cli history模式实现tomcat部署报404的解决方式
Sep 06 Javascript
微信小程序自定义弹出模态框禁止底部滚动功能
Mar 09 Javascript
Vue + element 实现多选框组并保存已选id集合的示例代码
Jun 03 Javascript
jQuery实现回到顶部效果
Oct 19 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下打开URL地址的几种方法小结
2010/05/16 PHP
服务器变量 $_SERVER 的深入解析
2013/07/02 PHP
php获取网页上所有链接的方法
2015/04/03 PHP
Yii2使用swiftmailer发送邮件的方法
2016/05/03 PHP
简述php环境搭建与配置
2016/12/05 PHP
php支付宝APP支付功能
2020/07/29 PHP
php更新cookie内容的详细方法
2019/09/30 PHP
laravel框架实现后台登录、退出功能示例
2019/10/31 PHP
纯js简单日历实现代码
2013/10/05 Javascript
For循环中分号隔开的3部分的执行顺序探讨
2014/05/27 Javascript
javascript继承的六大模式小结
2015/04/13 Javascript
jQuery判断多个input file 都不能为空的例子
2015/06/23 Javascript
javascript获取select值的方法分析
2015/07/02 Javascript
jquery简单倒计时实现方法
2015/12/18 Javascript
JavaScript操作class和style样式代码详解
2016/02/13 Javascript
微信小程序 wx:key详细介绍
2016/10/28 Javascript
JavaScript队列、优先队列与循环队列
2016/11/14 Javascript
JavaScript构建自己的对象示例
2016/11/29 Javascript
详解AngularJS1.6版本中ui-router路由中/#!/的解决方法
2017/05/22 Javascript
JavaScript变量声明var,let.const及区别浅析
2018/04/23 Javascript
微信小程序生成海报分享朋友圈的实现方法
2019/05/06 Javascript
jQuery实现获取多选框的值示例
2020/02/07 jQuery
Vue实现图书管理案例
2021/01/20 Vue.js
python套接字流重定向实例汇总
2016/03/03 Python
python 调用HBase的简单实例
2016/12/18 Python
利用Pyhton中的requests包进行网页访问测试的方法
2018/12/26 Python
python数值基础知识浅析
2019/11/19 Python
Django admin 实现search_fields精确查询实例
2020/03/30 Python
Django-imagekit的使用详解
2020/07/06 Python
通过css3的filter滤镜改变png图片的颜色的示例代码
2020/05/06 HTML / CSS
获取邓白氏信用报告:Dun & Bradstreet
2019/01/22 全球购物
职工运动会邀请函
2014/01/19 职场文书
校园运动会广播稿
2014/10/06 职场文书
2015国庆节宣传语
2015/07/14 职场文书
学习弘扬焦裕禄精神心得体会
2016/01/23 职场文书
Java Lambda表达式常用的函数式接口
2022/04/07 Java/Android