jQuery源码分析(四): get(n)与eq(n)

前端基础 2016-10-31

起步

构造器之后,就是定义一些函数的了:

jQuery.fn = jQuery.prototype = {
    jquery: version,
    constructor: jQuery,
    selector: "",
    length: 0,
    toArray: function() {},
    get: function( num ) {},
    pushStack: function( elems ) {},
    eq: function( i ) {},
    push: push,
    sort: arr.sort,
    splice: arr.splice
}

看到geteq不经想起那时候用jq的时候特地去找了他们的区别。

get与eq的区别

简单的说就是eq返回的是一个jquery对象,可以用jq的方法;而get返回的是一个传统html DOM对象。

$("p").eq(0).css("color");  //对
$("p").get(0).css("color"); //错 应该是$("p").get(0).style.color

get的实现

get函数的实现比较简单:

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 );
},

这个this指的是jQuery对象,this[num]将对象当做是数组用,jQuery对象本身就是数组集合。this.xxxthis['xxx']是等价的一样,但如果属性是有空格那些就得用obj['xxx']方式了。用console.log($('p'));查看确实有纯数字属性:

20161031134435.png

点开一个可以看到:

20161031134854.png

看到innerHTMLinnerText了,没错,这就是原生的DOM对象,不加任何防腐剂。甚至可以将它与document.getElementById()做比较(我做了$().get(0)==getElementById()返回的是true)。

eq的实现

eq: function( i ) {
    var len = this.length,
    j = +i + ( i < 0 ? len : 0 );
    return this.pushStack( j >= 0 && j < len ? [ this[j] ] : [] );
},

eq的逻辑和get是一样的,你能看到这边也使用了this[j],[this[j]]返回是数组形式,pushStack只是将对象包装为jq对象:

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大约在423行
merge: function( first, second ) {
    var len = +second.length,
        j = 0,
        i = first.length;

    for ( ; j < len; j++ ) {
        first[ i++ ] = second[ j ];
    }

    first.length = i;
    return first;
},

其中,this.constructor()就是$(),这是会新创建一个jq对象.elems是原生的DOM对象,通过merge()函数将他们合并。这样DOM对象就被包装了变成jq对象了。

总结

eq返回的是一个jQuery对象,get返回的是一个DOM对象。一个原生的DOM对象obj = document.getElementById("my");也可以通过$(obj)将其变为jq对象。所以,$().eq(1)$( $().get(1) )是等价的。


本文由 hongweipeng 创作,采用 知识共享署名 3.0,可自由转载、引用,但需署名作者且注明文章出处。

赏个馒头吧