jQuery.fn is one of those things that exists mainly for historical reasons.

In the very first versions of jQuery, $.fn was *not* the same as
$.prototype. (There was no jQuery object by that name in those days, just a
$ object.)

$.prototype wasn't used for anything; instead, every time a jQuery object
was created, all of the method references found in $.fn were copied, one by
one, into the new jQuery object.

As you can guess, this was a bit slow, and I came up with a patch to use
$.prototype in the conventional manner instead of copying all the methods.
$.fn was kept as an alias of $.prototype for compatibility with existing
plugins that already used $.fn.

So, the code:

    jQuery.fn.init.prototype = jQuery.fn;

could be written:

    jQuery.prototype.init.prototype = jQuery.prototype;

What does that do? It gives the init() function the same prototype as the
jQuery object. So when you call init() as a constructor in the "return new
jQuery.fn.init( selector, context );" statement, it uses that prototype for
the object it constructs. This lets init() substitute for the jQuery
constructor itself.

Now I'm curious: What's the benefit you gain by using this pattern in your
own code?

-Mike

> From: Andrei Maxim
> 
> Hi all,
> 
> I've recently grabbed the latest edition of the Rhino book 
> and I'm trying to build some small JavaScript libraries in 
> order to get the hang of coding in JS. I've been also reading 
> lots of blog posts and I've been looking at the code of 
> several major JS frameworks and libraries, like jQuery, 
> Prototype and script.aculo.us and I'm trying to understand 
> why the author wrote that code.
> 
> For some reason, I've been growing very fond of the pattern 
> used in jQuery to create the jQuery object. Here's the code 
> I'm talking about, taken from v1.2.6:
> 
> var jQuery = window.jQuery = window.$ = function( selector, 
> context ) {
>       // The jQuery object is actually just the init 
> constructor 'enhanced'
>       return new jQuery.fn.init( selector, context ); };
> 
> [...]
> 
> jQuery.fn = jQuery.prototype = {
>       init: function( selector, context ) {
>               // Make sure that a selection was provided
>               selector = selector || document;
> 
>               // Handle $(DOMElement)
>               if ( selector.nodeType ) {
>                       this[0] = selector;
>                       this.length = 1;
>                       return this;
>               }
>       [...]
> };
> 
> // Give the init function the jQuery prototype for later 
> instantiation jQuery.fn.init.prototype = jQuery.fn;
> 
> When I tried to add my custom object, I had some problems 
> with accessing the functions I defined inside 
> jQuery.prototype. Only after a couple of hours I added a line 
> similar to jQuery.fn.init.prototype = jQuery.fn and then it 
> magically worked.
> 
> However, I don't get what's going on.
> 
> From what I understood reading JavaScript docs, "jQuery.fn = 
> jQuery.prototype" means that we "reference" jQuery object's 
> prototype and I'm guessing this is used just to simplify the 
> code (I might be extremely wrong on this). Also, the defined 
> functions are shared by each jQuery object.
> 
> But why do we need to add "jQuery.fn.init.prototype = 
> jQuery.fn" for things to work?
> 
> Thanks a lot,
> Andrei
> 

Reply via email to