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插件制作 提示框插件实现代码
Aug 17 Javascript
jquery中$(#form :input)与$(#form input)的区别
Aug 18 Javascript
sencha ext js 6 快速入门(必看)
Jun 01 Javascript
jQuery如何封装输入框插件
Aug 19 Javascript
获取JavaScript异步函数的返回值
Dec 21 Javascript
微信小程序微信支付接入开发实例详解
Apr 12 Javascript
Vue.js实现模拟微信朋友圈开发demo
Apr 20 Javascript
基于webpack4.X从零搭建React脚手架的方法步骤
Dec 23 Javascript
JS事件流与事件处理程序实例分析
Aug 16 Javascript
OpenLayers加载缩放控件使用方法详解
Sep 25 Javascript
微信小程序绘制半圆(弧形)进度条
Nov 18 Javascript
vue前端和Django后端如何查询一定时间段内的数据
Feb 28 Vue.js
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
ThinkPHP访问不存在的模块跳转到404页面的方法
2014/06/19 PHP
PHP使用递归方式列出当前目录下所有文件的方法
2015/06/02 PHP
实现变速回到顶部的JavaScript代码
2011/05/09 Javascript
JQuery AJAX 中文乱码问题解决
2013/06/05 Javascript
jQuery实现图片放大预览实现原理及代码
2013/09/12 Javascript
详解jquery uploadify 上传文件
2013/11/09 Javascript
javascript对话框使用方法(警告框 javascript确认框 提示框)
2014/01/07 Javascript
深入探讨JavaScript String对象
2015/03/09 Javascript
javascript中attachEvent用法实例分析
2015/05/14 Javascript
概述jQuery的元素筛选
2016/11/23 Javascript
js弹出窗口简单实现代码
2017/03/22 Javascript
使用 Vue.js 仿百度搜索框的实例代码
2017/05/09 Javascript
详解vue slot插槽的使用方法
2017/06/13 Javascript
Angular 2父子组件之间共享服务通信的实现
2017/07/04 Javascript
Angular中响应式表单的三种更新值方法详析
2017/08/22 Javascript
node.js环境搭建图文详解
2018/09/19 Javascript
微信小程序+云开发实现欢迎登录注册
2019/05/24 Javascript
原生js实现的观察者和订阅者模式简单示例
2020/04/18 Javascript
js实现菜单跳转效果
2020/12/11 Javascript
Python基于scrapy采集数据时使用代理服务器的方法
2015/04/16 Python
一个基于flask的web应用诞生 组织结构调整(7)
2017/04/11 Python
Python实现1-9数组形成的结果为100的所有运算式的示例
2017/11/03 Python
Python中的pygal安装和绘制直方图代码分享
2017/12/08 Python
将python运行结果保存至本地文件中的示例讲解
2019/07/11 Python
Python基于unittest实现测试用例执行
2020/11/25 Python
CSS3实现swap交换动画
2016/01/19 HTML / CSS
澳大利亚排名第一的在线酒类商店:MyBottleShop
2018/04/26 全球购物
初中生三年学习生活的自我评价
2013/11/03 职场文书
2014年学习雷锋活动总结
2014/03/01 职场文书
决心书标准格式
2014/03/11 职场文书
演讲比赛策划方案
2014/06/11 职场文书
医疗专业毕业生求职信
2014/08/28 职场文书
教师党员先进性教育自我剖析材料思想汇报
2014/09/24 职场文书
护士个人年终总结
2015/02/13 职场文书
2015年试用期工作总结范文
2015/05/28 职场文书
mysql函数之截取字符串的实现
2022/08/14 MySQL