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能取到上一个合集的原因了。