JQuery source code series (IX) backtracking mechanism


WelcomeMy columnView a series of articles.

After learning prevobject, I found that there was a problem in my blog about pushstack function. Originally, I thought this pushstack function was an ordinary function. It accepted a DOM (array) parameter, merged the parameter into a jQuery object and returned the jQuery object.

JQuery source code series (IX) backtracking mechanism

Later, I also wondered why I couldn’t see the use of this function for some time, and why I put it in jQuery FN, until today, I suddenly realized.

Prevobject object of jquery

When we create a new jQuery object, we will find one in its propertiesprevObjectIf you only look at the “previous object” from the name, how is it used.

JQuery source code series (IX) backtracking mechanism

Inside the jQuery object, there is a jQuery object stack to maintain all jQuery objects that have been operated. In this way, you can write fluent jQuery code, such as operating the parent element, operating the child element, and then returning to the parent element.

But in fact, this stack does not exist. We know that arrays can be used as stacks or queues. Does it mean that jQuery has such an array to store this object stack. The answer is no, why, because it doesn’t have to be so troublesome.Think about it this way. If each jQuery object has a pointer to the previous object, it will indirectly form a jQuery object stack.If there is only one element in the stack, prevobject points to by defaultdocument。 Prevobject is used to implement the object stack. For example:

<div id="view">
  < H1 class = "header" > title</h1>
  < strong class = "espe" > key points < / strong >

For the HTML above:

var $view = $("#view");
//The $header is obtained from the $view operation
var $header = $view.find('.header');
$header.prevObject === $view; // true

However, when using, we ignore the object stack and define different jQuery objects to point to the parent and child elements. As in the above example, since $view and $header are defined, prevobject is not required.

jQuery. fn. End and jQuery fn. addBack

These two functions are actually the application of prevobject. You can understand it by taking an example. It is still the HTML above:

$('#view').find('.header').css({'color': 'red'})
  .find('.espe').css({'color': 'white'})

YesendAfter that, the currently executed jQuery object becomes$('#view')So you can continue to perform the find operation and so on. If you don’t add it, this paragraph won’t succeed. It can be seen that if you write jQuery like this, it is not only elegant, but also very efficient.

End and addback are different,end()The function simply performs the out of stack operation and returns the jQuery object out of the stackaddBack()The function does not execute out of the stack, but forms a new object from the top of the stack object and the current object into the stack:

  . CSS ({'color':'Red '}) // full red

The above code will set the color of #view’s three child elements to red.

Correlation function source code

Let’s look at the pushstack function again. This function is not only infn.find()Functions, many prototype functions involving jQuery DOM operations have appeared, andPreviously introducedAn important part of the prevobject object is ignored:

jQuery.fn.pushStack = function (elems) {

  //Merge elems into jQuery object
  var ret = jQuery.merge(this.constructor(), elems);

  //Implementation object stack
  ret.prevObject = this;

  return ret;

pushStackA new jQuery object is generatedretretThe prevobject property of the object refers to the jQuery object that calls the pushstack function, thus forming a stack chain. Other prototype methods such as find, nextall, filter, etc. can call the pushstack function to return a new jQuery object and maintain the object stack.

When we know that all jQuery methods have a prevobject attribute, let’s take a look at the end method:

jQuery.fn.end = function () {
  return this.prevObject || this.constructor();

There is also the addback method:

jQuery.fn.addBack = function (selector) {
  //It can be seen that addback with parameters will filter prevobject
  return this.add(selector == null ? this.prevObject : this.prevObject.filter(selector));

It’s interspersed with onefn.addmethod:

jQuery.fn.add = function (selector, context) {
  return this.pushStack(
      jQuery.merge(this.get(), jQuery(selector, context))));

There should be no need to explain. The source code is clear.


As I have said before, end or pushstack methods are rarely used. However, in jQuery’s internal prototype methods, such as find, nextall, filter, etc., they are frequently used. This method of encapsulating a jQuery is great and will maintain the object stack well. Anyway, this is the charm of jQuery!

reference resources

JQuery 2.0.3 source code analysis backtracking magic end() and pushstack()
jQuery API .end()
jQuery API .addBack()

This paper is based on GitHubSource addressWelcome to star.

WelcomeMy blogcommunication.