Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
282 views
in Technique[技术] by (71.8m points)

javascript - How can jQuery behave like an object and a function?

jQuery or $ seems to be a function:

typeof $; // "function"

And it acts like one:

$('div').removeClass(); // $ constructs a new object with some methods like removeClass

But when I drop the function parentheses it behaves like an object:

$.each(/* parameters */); // $ is an object with some methods like each

I'd like to know how this is possible and how I can implement this behaviour to my own functions.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Functions are also objects, so $.each can be defined in a similar way as an Object.

JavaScript is a prototypical language. For jQuery, this means that every instance of $ inherits methods from jQuery.prototype.See Notes

A very rough demo, to achieve the similar behaviour:

(function() { // Closure to not leak local variables to the global scope
    function f(a, b) {
        //Do something
    }
    // Prototype. All properties of f.prototype are inherited by instances of f.
    // An instance of f can be obtained by:    new f, new f(), Object.create(f)
    f.prototype.removeClass = function(a) {
        return a;
    };
    function $(a, b) {
        return new f(a, b); // <--- "new f" !  
    } 
    $.each = function(a) {
        alert(a);             
    };
    window.$ = $; // Publish public methods
})();

//Tests (these do not represent jQuery methods):
$.each("Foo");                   // Alerts "Foo" (alert defined at $.each)
alert($().removeClass('Blabla'));// Alerts "Blabla"

Notes

jQuery's root method is defined as follows (only relevants parts are shown):

(function(win) {
    var jQuery = function (selector, context) {
        return new jQuery.fn.init(selector, context, rootjQuery);
    };
    //$.fn = jQuery.fn is a shorthand for defining "jQuery plugins".
    jQuery.fn = jQuery.prototype = {
        constructor: jQuery,
        init: function( /* ..parameters.. */ ) { 
            //.... sets default properties...
        }
        //....other methods, such as size, get, etc...
        //.... other properties, such as selector, length, etc...
    };
    jQuery.fn.removeClass = function() { // (Actually via jQuery.fn.extend)
        // ... method logic...
    };  //...lots of other stuff...

    win.$ = win.jQuery = jQuery; //Publish method
})(window);

The advantage of the prototype method is that it's very easy to chain methods and properties. For example:

$("body").find("div:first").addClass("foo");

A method to implement this feature could be:

$.fn.find = function(selector) {
    ...
    return $(...);
};

If you're interested in jQuery's real implementation, have a look at the annotated source code:


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...