I just started learning jQuery and OO Javascript, so I am trying to figure out which belongs to which and what they do. I came across this code in the JQuery documentation
(function($sub) {
$sub // a subclass of jQuery
$sub === jQuery; //= false
$sub.fn.myCustomMethod = function(){
return 'just for me';
}
$sub(document).ready(function() {
$sub('body').myCustomMethod(); //= 'just f开发者_开发问答or me'
});
})(jQuery.subclass());
Questions:
- Why is (function surrounded by () ?
- What does this mean (jQuery.subclass()); ? Is this a JQuery thing or part of regular javascript?
Thanks
(1) self invoking functions
function() {
}();
are both invalid on their own as they cause a syntax error and it's confusing to see it invoked at the bottom.
This is why the JavaScript community uses (
at the start of self invoking function to let other readers of the code be aware that it is not a normal function.
var o = (function() {
})();
Whenever I see a function that starts with (
I know that it is self invoking. This means it is immediately executed and that o
contains the return value of the function and not the function.
(2) jQuery subclasses
Be wary that using subclasses relies on having jQuery 1.5. I recommend you wait for the official release rather then using 1.5 RC1 as there are a few bugs to iron out.
jQuery.subclass
is part of the jQuery 1.5 beta. It's a new feature of jQuery where it essentially makes a subclass of jQuery.
This means that anything that you add to jQuery.subclass won't be added to jQuery. A jQuery subclass has all the functionality of jQuery but anything you add or change won't effect "global jquery"
Annotated sample source
// self invoking function. This creates a closure so that anything declared in
// this function is local and doesn't effect global state
(function($sub) {
$sub // a subclass of jQuery
$sub === jQuery; //= false
// here we extend $.fn with a new method. This actually extends the prototype of $sub
// $sub.fn === $sub.prototype === $()
// $sub.fn is actually a new jQuery object. This means that when using $sub we first look
// for method defined on $sub.fn, and if there aren't any we look on methods defined
// on $.fn. A useful feature of this is that you can overwrite methods
$sub.fn.myCustomMethod = function(){
return 'just for me';
}
// We can "overwrite" methods of jQuery by hiding the original methods.
$sub.fn.attr = function() {
alert("new attr!");
// you can go into $sub.superclass to get the original $ object and call methods there
$sub.superclass.attr.apply(this, arguments);
}
// This calls .ready from the original jQuery
$sub(document).ready(function() {
$sub('body').myCustomMethod(); //= 'just for me'
});
// we pass in a subclass of jquery at the bottom. This means that $sub has all the
// functionality of $ but doesn't change $ itself.
})(jQuery.subclass());
DISCLAIMER .__proto__
is deprecated and bad. It is only used to illustrate what the prototype chain looks like with jQuery.subclass.
For those who understand .__proto__
(this gets the prototype of the constructor of the object)
var $sub = jQuery.subclass();
$sub.__proto__ === $sub.fn; // true
$sub.__proto__.__proto__ === $.fn; // true
// example of .__proto__
function constructor() { }
var o = new constructor;
o.__proto__ === constructor.prototype; // true
If further explanation is needed or if you're curious about anything else please do mention it. I may have glossed over something that I think was obvious.
- It is an expression returning an anonymous function. The resulting function is immediately called (the second pair of parentheses) using jQuery.subclass()) as the single parameter.
- It's a jQuery thing. It allows you to create a 'custom' JQuery class while still leaving the unaltered JQuery available for other scripts on your page (http://api.jquery.com/jQuery.subclass/)
I'll try to explain it
- function is surrounded by (), because this is how you make a javascript closure. The code inside () will not be visible for the global scope (window). The code is making anonymous function with one argument and it's calling the function right after it's declaration with jQuery.subclass() passed as the function argument.
For example :
function dirty($arg) {...}
is visible from the global scope
(function dirty($arg) {...})("some arg");
is not visible from the global scope - it creates a function with it's own scope, calls it immediately and if it's not assigned to a variable, the reference is lost
In this way you can alter jQuery's funcitons without changing the global jQuery object. I don't know how can this be useful, but that's what it does :) 2. From the jQuery API docs -
Creates a subclass of the jQuery object, allowing you to add additional or altered jQuery methods and properties without affecting the global jQuery.
精彩评论