What really happens when jQuery is passed in by itself?

So, I have a puzzle, and I hope someone already has the answer. Reading the jQuery source, I still don't understand what is going on here.

$('#div') //returns a jQuery object $( $('#div') ) // returns an identical jQuery object $( $( $( $( $( $('#div') ) ) ) ) ) // returns the same idential object 

I ran instances in plugin development where I don't know how to expect a complaint selector or jQuery object. In these cases, I just passed the selector or jQuery object to jQuery, so I am guaranteed the jQuery object I want. It works well, but it feels too magical. What happens when I do this? Is there a better way?

+4
source share
2 answers

I think that in the function $(...) there is some basic case like.

  • In Arg, it is of type String, pass this and find or create an HTML Dom element, then encapsulate it in a jQuery object.
  • In Arg is of type HTML Dom, encapsulates an object in a jQuery object
  • There is a jQuery object in Arg, return it as it is

But in fact, in this case, there is also mining debugging and error checking before that.

More details at http://jsapi.info/jquery/1.8.0/jQuery.fn.init What I see from the code, if we have one.

 var x = $('#div'); var y = $(x); 

the contents of x and y equal but the memory of x and y not equal.

Let's say that we have:

 class $ { var x; $($ t) { this.x = tx } } 

This will be done if all $ calls have the same internal value but are not as real as two different objects.

+1
source

Before answering this question, you need to understand that $ (...) returns a special object with properties such as an array. From the documentation:

JQuery factory function The $ () function returns a jQuery object that has many array properties (length, array access operator [], etc.), but is not quite the same as the array, and some missing built-in arrays methods (such as .pop () and .reverse ()).

So here is what happens.

  • Regardless of the type of selector, new jQuery.fn.init( selector, context, rootjQuery ); , therefore, a new object is created and its properties are set in this constructor init() .

  • The argument $ (...) is tested for void, DOMElement, string or function (via isFunction)

All checks fail, and as a result, the following code is called.

 if (selector.selector !== undefined ) { this.selector = selector.selector; this.context = selector.context; } return jQuery.makeArray( selector, this ); 

The makeArray () function turns the provided selector into an array-like object by simply setting the this.length property and this.ret[0]=..., this.ret[1]=... so that it "feels" like an array while it remains an object based on the jQuery prototype (aka $.fn ). Remember that this in the code above is just a new object with $.fn in the prototype. In addition, the .selector and .context copied from the original to this.

It is important to note that, for example, the .prevObject Property will be lost, but a new one may be added depending on the method chain.

In general, it takes time and memory, and it probably makes sense to just check .selector when someone can pass the jQuery object to your plugin. On the other hand, a new instance with the same behavior as the original may be useful.

+1
source

Source: https://habr.com/ru/post/1435148/


All Articles