jQuery如何表现得像一个对象和一个函数?

jQuery$似乎是一个函数:

 typeof $; // "function" 

它就像一个:

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

但是当我删除函数括号时,它的行为就像一个对象:

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

我想知道这是如何可行的,以及如何将这种行为实现到我自己的函数中。

函数也是对象,因此可以以与Object类似的方式定义$.each

JavaScript是一种原型语言。 对于jQuery,这意味着$每个实例都从jQuery.prototypeinheritance方法。 见注释

一个非常粗略的演示,实现类似的行为:

 (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" 

笔记

jQuery的root方法定义如下(仅显示相关部分):

 (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); 

prototype方法的优点是链接方法和属性非常容易。 例如:

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

实现此function的方法可以是:

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

如果您对jQuery的实际实现感兴趣,请查看带注释的源代码:

  • jQuery核心 - 构造函数和基本方法的定义。
  • jQuery.fn.extend用于向jQuery添加removeClass等 。
  • jQuery 1.7.1 。

所有function都以这种方式工作

 function fn() { alert("hi mom"); } fn.foo = "bar"; 

在JavaScript中,函数是一种对象。 具体来说,函数是从Object派生的Function对象的实例。 jQuery利用了这个事实并从jQuery函数对象中挂起了一些“静态”方法。

jQuery的创建者John Resig在http://ejohn.org/apps/learn/上有一个很好的关于这个主题的教程。 这可能会为您提供有关如何在您自己的代码中利用JavaScript的这一function的一些想法。