jQuery.fn is the prototype upon which all new instances of jQuery are based. It exists so that third party code (and jQuery itself!) can extend jQuery using code like this:
jQuery.fn.myMethod = function() {...}
However, currently in jQuery, all the following four are references to the same object!
- jQuery.fn
- jQuery.prototype
- jQuery.fn.init.prototype
- jQuery.prototype.init.prototype
And that's not all: since jQuery and $ are (usually) aliases of each other, you can substitute jQuery for $ in any of the above, making 8 references to jQuery.fn.
So why have they given the same thing all those different names? Partially historical, partially necessary for prototypal inheritance.
jQuery.fn is pretty important, because both jQuery itself and lots of existing code rely on referring to it that way when extending jQuery, so that's why that's there. It's also nice and short which makes it a bit more friendly to type and read back than the other two, though I must say that the name 'fn' is confusing to me.
As for jQuery.prototype, once that reference is created it's never referred to in jQuery itself, so it's not clear what it's doing there. With knowledge of prototypal inheritance you may think that it's there so you can use jQuery with the new operator like this:
obj = new jQuery(selector);
but the jQuery() constructor does not use the new object that would be created inside it, and instead returns an object created elsewhere - in jQuery.fn.init() in fact. jQuery.prototype is not needed. Presumably, it's there for third party compatibility - so third party code can use jQuery.fn and jQuery.prototype interchangeably.
Which brings us to jQuery.fn.init.prototype. This reference is needed because it serves as the prototype for the jQuery.fn.init() constructor. It's in this constructor function that the actual creation of new jQuery objects happens, and in this case they are created using prototypal inheritance, which refers to a property of the constructor called 'prototype' when creating a new object, giving that new object to the constructor as the 'this' keyword.
Lastly, jQuery.prototype.init.prototype is just a crazy consequence of having jQuery.fn and jQuery.prototype referring to the same thing. You wouldn't use it.
Note that the following 4 expressions are all equivalent in jQuery, even though they might not be all be the recommended way. All these return a new object which uses jQuery.fn as a prototype - in fact all of these call jQuery.fn.init() as a constructor. And don't forget you can usually substitute jQuery with $.
jQuery()
new jQuery()
new jQuery.fn.init()
new jQuery.prototype.init()
jQuery tends to offer a lot of different ways of doing the same thing, or even referring to the same method or property. I guess you could say this about the browser APIs or the DOM too. But it's bound to make the task slightly more difficult for jQuery's developers who need to make sure future releases are backwards compatible.