Ashley’s Blog

A blogging framework for Ashley.

JQuery Find and prevObject

jQuery内部维护着一个jQuery对象栈。每个遍历方法都会找到一组新元素(一个jQuery对象),然后jQuery会把这组元素推入到栈中。 每个jQuery对象都有三个属性:context、selector和prevObject,其中的prevObject属性就指向这个对象栈中的前一个对象,而通过这个属性可以回溯到最初的DOM元素集中。 一般通过end()以及addBack()方法实现内部栈的调用 例如$(‘aaa’).find(‘div’).css(…).end() //从子 div 那里回来了

find: function( selector ) {
    var i,
        len = this.length,
        ret = [],
        self = this;
    /*
     *如果不是 string,那就应该是一个 Jquery 对象
     *过滤或者说寻找到该对象的同时通过 pushStack 把该对象压入jQuery对象栈的顶端
     */
    if ( typeof selector !== "string" ) {
        return this.pushStack( jQuery( selector ).filter(function() {
            for ( i = 0; i < len; i++ ) {
                if ( jQuery.contains( self[ i ], this ) ) {
                    return true;
                }
            }
        }) );
    }

    for ( i = 0; i < len; i++ ) {
    //jQuery.find 等于 sizzle,sizzle 的内容以后再分析。结果在 ret 中呢
        jQuery.find( selector, self[ i ], ret );
    }

    // Needed because $( selector, context ) becomes $( context ).find( selector )
    // 没看懂,为什么会有重复?
    // 但是pushStack的执行是毋庸置疑的
    ret = this.pushStack( len > 1 ? jQuery.unique( ret ) : ret );
    ret.selector = this.selector ? this.selector + " " + selector : selector;
    return ret;
}

然后就是 pushStack 和 end 方法

    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)
    //做了一次关键的链接,把执行 find 的 JQuery 对象赋给了返回结果的prevObject
    //通俗点说就是我知道了我的上家是谁
    ret.prevObject = this;
    ret.context = this.context;

    // Return the newly-formed element set
    return ret;
},
    end: function() {
    //返回我的上家
    return this.prevObject || this.constructor(null);
}

还是有不明白的地方以后再回过来看吧 这些 Jquery 的解读大部分都是从 imooc 上 Aaron 的课程中学来的