jQuery原型方法first,last,eq,slice源码分析
这4个方法中前3个方法很常用大家都见过,但是slice方法可能会以为是数组方法,其实slice也是jQuery的一个原型方法,只不过是底层方法是为其他方法服务的(更具体点是为eq方法服务的),首先还是看下这几个方法前台是怎么使用的;
eq 概述 获取第N个元素
参数
一个整数,指示元素的位置,从集合中的最后一个元素开始倒数。(1算起)
示例
参数index描述:
//获取匹配的第二个元素 //HTML 代码: <p> This is just a test.</p> <p> So is this</p>
//jQuery 代码: $("p").eq(1)
//结果: [ <p> So is this</p> ]
参数-index描述:
//获取匹配的第二个元素 //HTML 代码: <p> This is just a test.</p> <p> So is this</p>
//jQuery 代码: $("p").eq(-2)
//结果: [ <p> This is just a test.</p> ]
first() 获取第一个元素
示例
描述:
获取匹配的第一个元素
//HTML 代码: <ul>
<li>list item 1</li>
<li>list item 2</li>
<li>list item 3</li>
<li>list item 4</li>
<li>list item 5</li>
</ul>
//jQuery 代码: $('li').first()
//结果: [ <li>list item 1</li> ]
last() 获取最后个元素
示例
描述:
获取匹配的最后个元素
//HTML 代码: <ul>
<li>list item 1</li>
<li>list item 2</li>
<li>list item 3</li>
<li>list item 4</li>
<li>list item 5</li>
</ul>
//jQuery 代码: $('li').last()
//结果: [ <li>list item 5</li> ]
下面来看1.7.1中的源码:
eq: function( i ) {
i = +i;
return i === -1 ?
this.slice( i ) :
this.slice( i, i + 1 );
},
first: function() {
return this.eq( 0 );
},
last: function() {
return this.eq( -1 );
},
slice: function() {
return this.pushStack( slice.apply( this, arguments ),
"slice", slice.call(arguments).join(",") );
},
东西其实不多而且都是相互引用,首先我们可以简单的分下他们的关系 first,last>eq>slice>pushStack;
所以最红结果的输出依赖pushStack方法,此方法介绍在上一篇随笔中http://www.cnblogs.com/yy-hh/p/4636106.html感兴趣的可以了解下或者参考源码;所以直接从slice方法开始;
在源码中可以看到是直接ruturn pushStack处理后的结果,而在pushStack方法中需要3个参数,第一个是待处理元素数组,第二个是调用的方法,第三个是传入的selector,其中真正作用的是第一个参数剩下的两个参数是作调试使用的,他最后会返回一个新的jQuery对象,并且会在这个对象中添加一个prevObject属性执行原来的或者叫执行此方法时的jQuery对象,具体的请参考介绍pushStack的随笔。下面重点来看下参数的处理:
slice.apply( this, arguments )
这个是一个数组的截取,其实是一个类数组或者特殊数组转换为纯数组的方法,前面我们介绍的toArray方法亦是如此
toArray: function() {
return slice.call( this, 0 );
},
这不过是这里并不是需要所有的元素而是仅仅保留数字下标的dom元素,为了更方便的理解我们在前台调用下这个方法然后观察源码中的结果变化:
<script>
$('div').slice();
</script>
slice: function() {
console.log(this);
console.log(this.toArray());
console.log(slice.apply( this, arguments));
return this.pushStack( slice.apply( this, arguments ),
"slice", slice.call(arguments).join(",") );
},
//Object { 0: <div>, 1: <div>, length: 2, prevObject: Object, context: HTMLDocument → test.html, selector: "div" }
//Array [ <div>, <div> ]
//Array [ <div>, <div> ]
结果是不是很明显呢?在未处理之前是一个jQuery对象,拥有众多属性和方法在使用toArray方法和slice.apply( this, arguments)结果是一样的仅仅保留的是两个dom元素,不是所有的非数组都是可以这样转化的一定要是从0开始下标而且有length属性的才可以或者更简单点可以使用for循环的。但是既然可以使用toArray方法直接不就行了干嘛还要在写一个用对象冒充一次呢,其实toArray方法只是arguments为0的特殊情况,toArray方法也是写得很清楚,如果我调用此方法加上参数就不一样了例如:
$('div').slice(0,1);
Object { 0: <div>, 1: <div>, length: 2, prevObject: Object, context: HTMLDocument → test.html, selector: "div" }
Array [ <div>, <div> ]
Array [ <div> ]
第二个参数“slice”就是从这个方法入栈的作为调试用,第三个参数是一个字符串arguments是类数组所以要对象冒充掉join方法 在上面例子的调用下就是"0,1" 最后来看看下slice方法最终返回的结果
console.log($('div').slice(0,1));
Object { 0: <div>, length: 1, prevObject: Object, context: HTMLDocument → test.html, selector: "div.slice(0,1)" }
如果不够清楚可以看下目录
console.dir($('div').slice(0,1));

prevObject属性指向未调用slice(也就是pushStack)方法时的对象 selector属性告诉我们是什么元素调用了什么方法入栈的以及参数是什么
理解了slice方法eq方法就很清晰了:
eq: function( i ) {
i = +i;
return i === -1 ?
this.slice( i ) :
this.slice( i, i + 1 );
},
返回slice的结果,其实我上面局的例子完全可以是eq方法调用转换而来,因为一般情况下我们是不会单独调用slice方法的例如:
$('div').eq(0);
执行完其实就是return this.slice(0,1);
first方法都是eq方法的特殊情况当值为0或1的时候,所以也不建议大家使用这个方法,不好听点叫脱裤子放屁多此一举啊,好听点就是增加调用开销啊。
分析完毕:如果您耐心的看完了此篇还是不知所云可能有以下几个原因:
1.js基础不够扎实比如slice,apply等方法的使用
2.没有了解pushStack方法,这个方法是很多jQuery方法的底层支持方法一定要先弄清楚
jQuery原型方法first,last,eq,slice源码分析的更多相关文章
- 设计模式(五)——原型模式(加Spring框架源码分析)
原型模式 1 克隆羊问题 现在有一只羊 tom,姓名为: tom, 年龄为:1,颜色为:白色,请编写程序创建和 tom 羊 属性完全相同的 10 只羊. 2 传统方式解决克隆羊问题 1) 思路分析(图 ...
- jquery dom ready, jqery2.1.1实现-源码分析
本文链接http://www.cnblogs.com/Bond/p/4178311.html jquery document ready的实现其很很简,虽说简单,其很很多人还是没去关注过它的实现.我 ...
- jQuery.access源码分析
基本理解 jQuery.attr是jQuery.attr,jQuery.prop,jQuery.css提供底层支持,jQuery里一个比较有特色的地方就是函数的重载, 比如attr,有如下几种重载 $ ...
- jQuery1.9.1源码分析--数据缓存Data模块
jQuery1.9.1源码分析--数据缓存Data模块 阅读目录 jQuery API中Data的基本使用方法介绍 jQuery.acceptData(elem)源码分析 jQuery.data(el ...
- 【集合框架】JDK1.8源码分析之Collections && Arrays(十)
一.前言 整个集合框架的常用类我们已经分析完成了,但是还有两个工具类我们还没有进行分析.可以说,这两个工具类对于我们操作集合时相当有用,下面进行分析. 二.Collections源码分析 2.1 类的 ...
- Java源码分析:关于 HashMap 1.8 的重大更新(转载)
http://blog.csdn.net/carson_ho/article/details/79373134 前言 HashMap 在 Java 和 Android 开发中非常常见 而HashMap ...
- ABP源码分析三十:ABP.RedisCache
ABP 通过StackExchange.Redis类库来操作Redis数据库. AbpRedisCacheModule:完成ABP.RedisCache模块的初始化(完成常规的依赖注入) AbpRed ...
- jQuery-1.9.1源码分析系列完毕目录整理
jQuery 1.9.1源码分析已经完毕.目录如下 jQuery-1.9.1源码分析系列(一)整体架构 jQuery-1.9.1源码分析系列(一)整体架构续 jQuery-1.9.1源码分析系列(二) ...
- Monkey源码分析之事件注入
本系列的上一篇文章<Monkey源码分析之事件源>中我们描述了monkey是怎么从事件源取得命令,然后将命令转换成事件放到事件队列里面的,但是到现在位置我们还没有了解monkey里面的事件 ...
随机推荐
- AIX下如何根据端口号查找相应的进程
1. $ netstat -Aan |grep 8080 f1000e0002321bb8 tcp 0 0 *.8080 *.* LISTEN 2. $ rmsock f1000e0002321bb8 ...
- Concise - 面向对象的,一致的前端开发框架
在当今世界,有许多前端开发的框架.那么,为什么还要再造一个框架呢?Concise 建立的目的是使你有很多的开箱即用的选项,让你能够方便的搭建移动友好的网站和 Web 应用程序.另外还包括一个简单的网格 ...
- 关注经典:CSS Awards 获奖网站作品赏析《第一季》
每天都有很多新的网站推出,其中不乏一些设计极其优秀的作品.这个系列的文章,我为大家挑选了2012年赢得 CSS Awards 大奖的50个最佳网站.这些鼓舞人心的网站作品代表了网页设计的最高水平,相信 ...
- APP数据接口开发的一些经验
刚接到这样的任务时,没有感觉到任何压力,不就是给移动端应用提供数据吗?那边发来参数,这边处理数据,返回JSON.做网站开发时经常使用ajax请求后台数据,不就是这么回事吗.于是,在确认完需求后就开始干 ...
- TCP/IP详解学习笔记(13)-TCP坚持定时器,TCP保活定时器
TCP一共有四个主要的定时器,前面已经讲到了一个--超时定时器--是TCP里面最复杂的一个,另外的三个是: 坚持定时器 保活定时器 2MSL定时器 其中坚持定时器用于防止通告窗口为0以后双方互相等待死 ...
- 轻松实现localStorage本地存储
相信大家都知道HTML5提供了localStorage和sessionStorage两个新功能,基于这两个功能我们可以实现web资源的离线和会话存储,如果你现在还在用Cookie来临时存储网络资源的话 ...
- C#项目””是针对”.NETFramework,Version=v4.5.2”但此计算机没有,需要修改为v4.5.1.
每次下载别人的代码都会出现这样的问题,以为是没有安装.NETFramework,就下载安装了,但是每次安装都会出现已安装高版本的4.6(Win10自带),无需下次安装,但是每次VS中都会显示有问题,而 ...
- 在MVC中使用async和await的说明
首先,在mvc中如果要用纯异步请不要使用async和await,可以直接使用Task.Run. 其次,在mvc中使用async和await可以让系统开新线程处理Task的代码,同时不必等Task执行结 ...
- 使用VS Code开发ASP.NET Core 应用程序
最新教程:http://www.cnblogs.com/linezero/p/VSCodeASPNETCore.html 使用VS Code开发ASP.NET Core 应用程序 准备 1.安装VS ...
- SQL如何增删修改字段
1: 新增字段: ) NULL EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'土地手续办理情况' , @level ...