jQuery源码浅谈系列---部分过滤选择器
----今天包含的是我们常用的slice,eq,first,last
之所有吧这些放一起,很大程度上因为它们的调用是相似的。
1. slice(start,[end]) 返回的是jQuery对象
-----参数说明:
- start {Integer} -----开始选取子集的位置。第一个元素是0,如果是负数,则可以从集合的尾部开始
- end {Integer} ----可选,结束选取自己的位置,如果不指定就是本身的结尾。
/*版本取的是1.4.2 原理上会调用Array.prototype.slice给内部的api---pushStack做参 参数处理上没有在()定义,而是从arguments里面获取 */ slice: function(){ return this.pushStack(slice.apply(this,arguments), "slice" ,slice.call(arguments).join(",")); }
2. eq(index)
--------获取第N个元素(index从0开始)返回的是jQuery对象
/* @param i ---index 从0开始 @依赖与jquery的slice */ eq: function(i){ //判断i ===-1 那么调用jQuery的slice return i === -1 ? this.slice(i) : this.slice(i, +i +1); }
3. first()
--------获取第一个元素 返回的是jQuery对象
/* 核心思想就是调用eq 传一个index为0的参数 */ first: function(){ return this.eq(0); }
4. last()
------获取最后一个元素
/* 核心思想还是调用jQuery的eq传一个参数index为-1 有的人会问为什么是-1 你看看Array的原生的slice从后面查找是不是-1 我也写过原生slice的一些文章可以参考 */ last: function(){ return this.eq(-1); }
其实作为外部接口来讲这些很简单和清晰,但是作为这些api实现的底层------pushStack才是核心。
/* 这边的push是引用原生的Array.prototype.push @param elems @param name ---如果是slice调用传过来的多是slice @param selector */ pushStack : function(elems,name,selector){ //创建一个新的jQuery对象 //当然如果你是一个多版本的研究者你会发现从1.5.1开始这边的代码变了 //var ret = this.constructor(); var ret = jQuery(); //会调用工具类判断参数elems是否是array if(jQuery.isArray(elems)){ push.apply(ret,elems); }else{ //如果不是数组的话调用merge的api //如果不清楚可以看看我的其他的merge的文章 jQuery.merge(ret,elems); } //绑定一个属性并赋值this对象给它 ret.prevObject = this; ret.context = this.context; if(name === "find"){ ret.selector = this.selector + (this.selector ? " " : "") +selector; }else if(name){ ret.selector = this.selector + "." +name+ "("+selector+")"; } return ret; }