jQuery源码笔记.jpg

jQuery源码 回溯处理的设计

2020-04-15  本文已影响0人  柠檬果然酸

本节内容
1.jQuery.end()

有这样一种情况

var aaron = $("#aaron");
aaron.find('li').click(function() {
    alert(1);
})
aaron.click(function() {
    alert(2);
})

在调用find('li')之后DOM元素由#aaron变成了<li>,当我们还想再#arron上绑定click事件的时候只能写成两行,而不能继续保持链式结构。而jQuery.end()方法就能将DOM回溯到#aaron,进而保持了链式调用。

aaron.find('li').click(function() {
    alert(1);
})
.end()
.click(function() {
    alert(2);
})

jQuery.end()
end方法就是回溯到上一个DOM合集,因此对于链式操作与优化,这个方法还是很有意义的。
既然是回溯到上一个DOM合集,那么肯定end方法中返回的就是一个jQuery对象了,所以我们看源码其实就是返回prevObject对象了。prevObject属性就指向这个对象栈中的前一个对象。

end: function() {
    return this.prevObject || this.constructor();
}

prevObject在什么情况下会产生?
在构建jQuery对象的时候,通过pushStack方法构建

jQuery.fn.extend({
    find: function(selector) {

        // 省略...

        // 通过sizzle选择器,返回结果集
        jQuery.find(selector, self[i], ret);

        // Needed because $( selector, context ) becomes $( context ).find( selector )
        ret = this.pushStack(len > 1 ? jQuery.unique(ret) : ret);
        ret.selector = this.selector ? this.selector + " " + selector : selector;
        return ret;
    }
}

接着我们看pushStack对象,作用就通过新的DOM元素去创建一个新的jQuery对象

// 这其实就是链表中的push方法,每push进来一个新的元素,都要保存上一个元素的位置
pushStack: function( elems ) {

    // Build a new jQuery matched element set
    // 因为constructor是指向构造器的,所以这里就等同于调用jQuery()方法了
    // 生成了一个新的jQuery对象
    var ret = jQuery.merge( this.constructor(), elems );

    // Add the old object onto the stack (as a reference)
    // 新的jQuery对象的prevObject属性指向旧的
    ret.prevObject = this;

    // Return the newly-formed element set
    return ret;
}

流程解析:
1.首先构建一个新的jQuery对象,因为constructor是指向构造器的,所以这里就等同于调用jQuery()方法了,返回了一个新的jQuery对象;

2.然后用jQuery.merge语句把elems节点合并到新的jQuery对象上;

3、最后给返回的新jQuery对象添加prevObject属性,我们看到prevObject其实还是当前jQuery的一个引用罢了,所以也就是为什么通过prevObject能取到上一个合集的原因了。

上一篇 下一篇

猜你喜欢

热点阅读