您的位置:首页 > Web前端 > JQuery

jQuery源码分析13--仿栈与队列的操作(数组的操作)

2015-12-30 10:26 483 查看


仿栈与队列的操作

jQuery既然是模仿的数组结构,那么肯定会实现一套类数组的处理方法,比如常见的栈与队列操作push、pop、shift、unshift、求和、遍历循环each、排序及筛选等一系的扩展方法。

jQuery对象栈是一个便于Dom的查找,提供的一系列方法,jQuery可以是集合元素,那么我们怎么快速的找到集合中对应的目标元素呢?正序,逆序。

jQuery提供了.get()、:index()、 :lt()、:gt()、:even()及 :odd()这类索引值相关的选择器,他们的作用可以过滤他们前面的匹配表达式的集合元素,筛选的依据就是这个元素在原先匹配集合中的顺序。

我们来分别看一下这几个选择器的实现原理:

get方法--是通过检索匹配jQuery对象得到对应的DOM元素,如下代码实现:

get: function(num) {
    return num != null ?
    // Return just the one element from the set
    (num < 0 ? this[num + this.length] : this[num]) :
    // Return all the elements in a clean array
    slice.call(this);
}


原理很简单,因为jQuery查询出来的是一个数组的DOM集合,所以就可以按照数组的方法通过下标的索引取值,当然如果num的值超出范围,比如小于元素数量的负数或等于或大于元素的数量的数,那么它将返回undefined。 假设我们页面上有一个简单的无序列表,如下代码:

<ul>
  <li id="foo">foo</li>
  <li id="bar">bar</li>
</ul>


如果指定了index参数,.get()则会获取单个元素,如下代码:

console.log( $( "li" ).get( 0 ) );


由于索引 index 是以 0 开始计数的,所以上面代码返回了第一个列表项
<li
 id="foo">foo</li>


然而,这种语法缺少某些 .get() 所具有的附加功能,比如可以指定索引值为负值:

console.log( $( "li" ).get(-1) );


负的索引值表示从匹配的集合中从末尾开始倒数,所以上面这个例子将会返回列表中最后一项:
<li
 id="bar">bar</li>


由于是数组的关系,所以我们有几个快速方法,比如头跟尾的取值:

first: function() {
    return this.eq( 0 );
},

last: function() {
    return this.eq(-1);
},

有一条语句要重点解释:


有一条语句要重点解释:

由于是数组的关系,所以我们有几个快速方法,比如头跟尾的取值:

Array.prototype.slice.call(argments,0)

Array.prototype.slice.call(thisArg[, arg1[, arg2[, ...]]])

成员介绍:

Array [object]

Array对象(即数组对象)

prototype [property]

Javascript的原型,此prototype非Prototype.js,可以暂且理解为Java中的静态属性/方法。

slice [Function]

数组切分方法,很有用的一个方法,具体请看这里,或那里。

call [Function]

神奇的方法,该方法是所有Function对象里的方法,所以slice就有这样一个方法。用于把Function对象里的this替换为目标对象。

作用效果:

Array.prototype.slice.call == [].slice

虽然运行结果是一个样的,前者的运行效率比后者大大提高

机理:

这里的slice方法就是一个Function对象。通常情况下,程序员通过如下方法调用Function,实质是普通的函数调用方法:

Array.slice(begin,end)

至于call()方法,METHOD: Function::call告诉我们,可以通过

Function.call(thisArg[, arg1[, arg2[, ...]]])

的形式调用一个Function对象,把当中的this对象替换为thisArg,即可以得到下面的代码:

Array.prototype.slice.call(obj,begin,end)

用伪代码模拟过程:

好,我们用伪代码的方法来模拟整个过程:

1 var mySlice=Array.prototype.slice;

2 alert(mySlice); //alert: function(begin[,end]){...},这是个“函数”

3 var array_empty=mySlice(begin,end); //create a new,empty array

4 set array_empty=obj; //此时,把obj赋给这个空的数组,使数组有了种子,

//这就是call()所做的事,“人工受精”

5 alert(array_empty); //这是个未定型的数组对象,由Javascript内部掌控着,

//这样看可能没什么结果,但有结果的话,就一定与obj有关

//下面是关键的一行:

6 var array_last=array_empty.slice(begin,end);

/**

*虽然之前说未定型,

*但返回的已经是一个数组了,我们对数组进行切割,但拿什么进行切?

*没错,就拿用obj制造出来的数组进行切割,

*一个新的数组对象产生了!

*/
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: