The jQuery
constructor sort of maps its functionality to another constructor, jQuery.fn.init
:
jQuery = function( selector, context ) {
return new jQuery.fn.init( selector, context, rootjQuery );
},
I'm wondering why.
This question is very similar, but even the answerer admits they didn't really answer the question as to why
This question is still unanswered
Is this just for organizational purposes? Rather than putting the init function inside the jQuery constructor definition, maybe the authors wanted to package it.
Is there any reason to have the .init()
method on the prototype? I don't think anyone ever uses $('.something')...init()...
This question shows that its not necessary to have .init
on the prototype.
And I just found this question in which Dan Herbert's answer suggests that it is simply for structure/readability purposes.
In conclusion, can I confirm that this constructor/prototype mapping funny-business is kind of unnecessary? It seems to me that the jQuery.fn.init
functionality could go:
jQuery
object (jQuery.init
vs jQuery.fn.init
)jQuery
function/constructor definition, replacing new jQuery.fn.init
and avoiding the jQuery.fn.init.prototype = jQuery.fn
mapping.fn. init() {...} , is given the jQuery prototype so that its object 'type' is of jQuery , and that all instances of it are actually instances of jQuery .
fn is an alias for jQuery. prototype which allows you to extend jQuery with your own functions.
The jQuery constructor sort of maps its functionality to another constructor
The fact is that jQuery
is not really a constructor function and shouldn't be seen as one either. By definition, a constructor's responsability is to initialize instance properties, which is not really the case with jQuery
. Also, calling new jQuery()
would be non-sense. jQuery
is a factory function for creating jQuery.fn.init
instances, nothing more.
Now, perhaps you are wondering why they simply didin't use jQuery
as a real constructor?
Well because they did not want a constructor that we call with new
all the time, they wanted a factory function. That's fine with me, however where I tend to disagree is that their pattern is very cryptic and doesn't quite reflect the intention.
It would have been far better in my opinion to chose better 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've pretty much only remapped jQuery.fn.init
to jQuery.Set
and it suddenly 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 a syntaxic sugar, instead of having to write jQuery.Set.prototype
all the time to modify the prototype.Now, in the source we also see that they do the following, which is kinda non-sense since jQuery
is not the real constructor, it's jQuery.prototype.init
and since we aren't creating jQuery
instances, setting jQuery.prototype
seems useless:
jQuery.fn = jQuery.prototype = {
constructor: jQuery
One of the reasons behind this is certainly that they want to accomodate people that might modify jQuery.prototype
instead of jQuery.fn
.
However another valid reason is that they perhaps wanted somejQueryObj instanceof jQuery
to returns true, while it normally wouldn't. If you take the pattern above (with jQuery.Set) you will notice that:
jQuery() instanceof jQuery; //false
jQuery() instanceof jQuery.Set; //true
However if we set the prototype
of jQuery
to jQuery.Set.prototype
, let's see what happens.
jQuery.prototype = jQuery.Set.prototype;
jQuery() instanceof jQuery; //true!
It's not easy to understand eveything that led to those design decisions and perhaps I am missing important points, but to me it seems their design is overcomplicated.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With