Functions are objects. They can have properties:
function F() {}
F.key = "value";
alert(F.key) // "value"
You can also use functions as constructors called with new:
function F(val) { this.key = val; }
var instance = new F("value")
alert(instance.key) // "value"
The difference as you can see is that the first version only adds a key memeber to the F function object, while the second one initializes a new key member on every instance created by newF.
When you call a function via new an instance object is automatically created and can be augmented by the this keyword. Every constructor returns this by default.
You can also add public methods to the function's prototype, and they will be available for all the instances. They can change their "state" (as you call it) individually using the this keyword.
function F(val) { this.state = val; } // unique
F.prototype.change = function() { this.state = "stuff"; }
var inst = new F("value")
var inst2 = new F("value")
alert(inst.state) // "value"
alert(inst2.state) // "value"
inst.change();
alert(inst.state) // "stuff"
alert(inst2.state) // "value"
jQuery
I can even tell you what jQuery is doing behind the scenes, but I don't think you really want to know. :)
var jQuery = 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 ) {
// ...
},
// ...
};
// Give the init function the jQuery prototype for later instantiation
jQuery.fn.init.prototype = jQuery.fn;
So basically $(selector) means newjQuery.fn.init(selector), it's just a shortcut for easier typing (and also to prevent the "bug" mentioned in the comments where fogetting new binds this to the global object, instead of the current instance).
Also, the so-called plug-ins added as jQuery.fn.ext are mapped to jQuery.fn.init.prototype as you can see in the last line, it's another shortcut. So when you call $(selector) everything that is added to jQuery.fn will also be on jQuery.fn.init.prototype and so the new instance will have those methods as $(selector).ext(...).
// as you use it today
jQuery.fn.plugin = function ( ... ) { ... }
$(selector).plugin( ... )
// as it would be without shortcuts
jQuery.fn.init.prototype.plugin = function ( ... ) { ... }
(new jQuery.fn.init(selector)).plugin( ... )
function f() {}; f.x = 0;works, but the rest of the question doesn't read like you talk about that.nullandundefined.