开发者

How does jQuery have the $ object constructor and the methods associated with the $?

开发者 https://www.devze.com 2023-03-12 08:03 出处:网络
How is it that jQue开发者_JAVA技巧ry can do $(\"#foo\").addClass(\"bar\") and $.ajax()? I\'m creating a micro javascript framework and want to create a new instance of an object, such as $(\"#hello\"

How is it that jQue开发者_JAVA技巧ry can do $("#foo").addClass("bar") and $.ajax()?

I'm creating a micro javascript framework and want to create a new instance of an object, such as $("#hello"). With this object there are associated methods, such as addClass, css, etc, just like with jQuery. So I could do something like

$("#foo").addClass("remove").css("color", "red");

I have been successful in creating this. However, when I want to call a method from this object, such as $.ajax, the constructor function is overwritten, and I can call $.ajax, but not $("#foo").

Basically, how can jQuery do both?


$ = function(arg) { console.log("$ function called with " + arg); }
$.ajax = function(arg) {console.log("$.ajax called with " + arg);}
$('foo');
$.ajax('bar');

http://jsfiddle.net/ac7nx/

I don't think there's any magic here. $ is just a name for the global function. Just keep in mind that in javascript, functions are first class objects that can have their own properties, including sub-functions, which is what $.ajax is.

Since you mentioned the constructor function, I should note that there are no OO objects being used here, just regular functions (no new keyword), so constructor functions don't play into this. If you are using the new keyword, that is probably where you are getting confused. If you want $('#foo') to return a new object, then inside the $ function's code you should create a new object using new and return that, which is what jQuery does, but the $ function itself is not a constructor and should not be called with new. Or in the case of something like $('#someID'), inside that function jQuery is getting an element object from the DOM and then returning that object, but still $ is just a regular function whose return value is an object, not a constructor function.


OK, the $ function is not only a function but an object, like all functions. So it can have methods. That's all that ajax is, a method of the $ function. So we can start off by doing this:

$ = function(obj) {
  // some code 
};
$.ajax = function (arg1, arg2) {
  // some ajax-y code
};

So far so good. Now, what on earth do we put in the $ function? Well it has to return an object and that object has to have some nice methods defined on it. So we'll need a constructor function (to give us new objects) and a prototype (to provide the nifty methods for those objects).

$ = function(obj) {
  var myConstructor = function (obj) {
    this.wrappedObj = obj;
  };

  myConstructor.prototype = {
    niftyMethod: function () {
      // do something with this.wrappedObj
      return this; // so we can chain method calls
    },
    anotherNiftyMethod: function (options) {
      // do something with this.wrappedObj and options
      return this; 
    }
  };

  return new myConstructor(obj);
};

So there we have it. We can do this:

var mySnazzObject = $("whatever");
mySnazzObject.niftyMethod().anotherNiftyMethod(true);        

And we can do this:

$.ajax("overthere.html", data);

Obviously jQuery does a heck of a lot more than that, and it does it in some really impressive ways, but that's the general idea.

UPDATE: AS @Raynos was kind enough to observe without supplying a constructive answer, my original code would create the prototype ad infinitum. So we make use of an anonymous autoexecuting function to declare the constructor and prototype separately:

(function () {
  var myConstructor = function (obj) {
    this.wrappedObj = obj;
  };

  myConstructor.prototype = {
    niftyMethod: function () {
      // do something with this.wrappedObj
      return this; // so we can chain method calls
    },
    anotherNiftyMethod: function (options) {
      // do something with this.wrappedObj and options
      return this; 
    }
  };

  var $ = function(obj) {
    return new myConstructor(obj);        
  };

  $.ajax = function (arg1, arg2) {
    // some ajax-y code
  };

  window.$ = $;  
}());


Two different things:

$.ajax is a prototyped function of jQuery called ajax.

While $('foo') is a call of the jQuery function and depending on the type of foo it reacts in different ways. At http://api.jquery.com/jQuery you can see that jQuery (almost the same as $) can react on three different types: selectors, html or callbacks.


You can imitate the magic jQuery behaviour as following:

//define
var _$ = {};
var $ = function(selector) {
           _$.html = function(args) {
                    alert("Doing the method 'html' with arguments " + args 
                           + " for selector " + selector);
                    return _$; //needed for pipeline
        };
        return _$; 
};

$.ajax = function(args){alert("Doing the method 'ajax' "); }

//and try
$("selector1").html("args1").html("args2");
$.ajax("args2");
0

精彩评论

暂无评论...
验证码 换一张
取 消