Why is the jQuery constructor mapped to jQuery.fn.init?

The jQuery constructor constructor maps its functionality to another constructor, jQuery.fn.init :

 jQuery = function( selector, context ) { return new jQuery.fn.init( selector, context, rootjQuery ); }, 

I wonder why.

This question is very similar, but even the answering machine admits that it didnโ€™t actually answer the question of why

This question is still not answered

Is it just for organizational purposes? Instead of placing the init function inside the jQuery constructor definition, perhaps the authors wanted to pack it.

Is there a reason to have a .init() method on a prototype? I don't think anyone has ever used $('.something')...init()...

This question shows that it does not need to have .init for the prototype.

And I just found this question in which Dan Herbert answers that this is just for structure / readability purposes.

In conclusion, can I confirm that this constructor / prototype representing a funny business is unnecessary? It seems to me that the jQuery.fn.init function can go:

  • Everywhere in the closure
  • On a jQuery object ( jQuery.init vs jQuery.fn.init )
  • Or, which makes sense to me: directly in the jQuery function / constructor definition, replacing new jQuery.fn.init and avoiding displaying jQuery.fn.init.prototype = jQuery.fn .
+6
source share
2 answers

JQuery constructor constructor maps its functionality to another constructor

The fact is that jQuery is not really a constructor function and should not be considered as one. By definition, the responsibility of the constructor is to initialize the properties of the instance, which is actually not related to jQuery . In addition, a call to new jQuery() will be insensitive. jQuery is a factory function for instantiating jQuery.fn.init , no more .

Now, you might be wondering why they just didn't use jQuery as a real constructor?

Good, because they did not want the constructor that we call with new all the time, they needed a factory function. This is fine with me, however, when I tend to disagree, it is that their pattern is very mysterious and does not quite reflect the intention .

It would be much better, in my opinion, to choose the best names:

 function jQuery(selector, context) { return new jQuery.Set(selector, context); } jQuery.Set = function (selector, context) { //constructor logic }; //allows syntaxic sugar jQuery.fn = jQuery.Set.prototype = { constructor: jQuery.Set, //methods }; 

I almost jQuery.fn.init to jQuery.Set , and all of a sudden this all makes more sense to me. When looking at the code above itโ€™s easy to see that:

  • jQuery is a factory function for creating jQuery.Set objects.
  • jQuery.fn exists only as syntactic sugar, instead of writing jQuery.Set.prototype all the time to change the prototype.

Now in the source we also see that they are doing the following, which is unreasonable, since jQuery not a real constructor, but jQuery.prototype.init and since we are not creating jQuery instances, setting jQuery.prototype seems useless:

 jQuery.fn = jQuery.prototype = { constructor: jQuery 

One reason for this is, of course, that they want to host people who can modify jQuery.prototype instead of jQuery.fn .

However, another important reason is that they may have wanted somejQueryObj instanceof jQuery return true, while this is usually not the case. If you take the template above (with jQuery.Set), you will notice that:

 jQuery() instanceof jQuery; //false jQuery() instanceof jQuery.Set; //true 

However, if we install prototype from jQuery to jQuery.Set.prototype , we will see what happens.

 jQuery.prototype = jQuery.Set.prototype; jQuery() instanceof jQuery; //true! 

It is not easy to understand everything that led to these design decisions, and maybe I miss important points, but for me it seems that their design is too complicated.

+4
source

It allows you to create a constructor chain. View...

So instead

 $('.someClass').hide(); $('.someOtherClass').hide(); 

You can do

 $('.someClass').hide().init.call($.fn, '.someOtherClass').hide(); 

It works, but it's also a joke.

-1
source

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


All Articles