2012-02-10 52 views
2

我正在为Web服务创建一个AJAX API,我希望能够调用类似jQuery的访问器。 jQuery的似乎是能够执行“jQuery的”作为一个功能,而且还用它来直接访问是功能EG的结果对象:可以像对象一样访问的jQuery风格的函数

jQuery(); 
jQuery.each({}); 

这是我似乎无法招拉脱:

myAPI('foo'); //output: 'foo' 
myAPI('foo').changeBar(); //output: 'foo' 1 
myAPI.changeBar(); //Error: not a function 

我看到类似问题的答案,这是有帮助的,但没有真正回答我的问题。

#8734115 - 非常有趣,但不能访问f.prototype设置的方法。

#2953314 - 使用多个操作来创建对象而不是单个函数。

这里是我的代码:

(function(window) { 

     var h = function(foo) { 
       // The h object is actually just the init constructor 'enhanced' 
       return new h.fn.init(foo); 
     }; 
     /** 
     * Methods defined at protoype. 
     */ 
     h.fn = h.prototype = { 
      constructor: h, 
      init: function(foo) { 
       console.log(foo); 
       return this; 
      }, 
      splice : function() {}, 
      length : 0, 
      bar : 0, 
      changeBar : function() { 
       this.bar++; 
       return this.bar; 
      } 
     }; 
     h.fn.init.prototype = h.fn; 

    //Publish 
    window.myAPI =h; 

}(window)); 

我敢肯定,我失去了一些东西简单:(

回答

5

什么jQuery是在那里做什么用jQuery作为两种功能:作为一个伪命名空间也就是说,你可以通话jQueryvar divs = jQuery("div");你可以使用它的属性,如:jQuery.each(...);

这是可能的,因为在JavaScript中,函数是第一类对象,所以你可以将它们任意添加属性:

function foo() { 
    alert("Foo!"); 
} 
foo.bar = function() { 
    alert("Bar!"); 
}; 

foo();  // "Foo!" 
foo.bar(); // "Bar!" 

这是字面上一切就是这么简单。

在调用barthis将是foo功能(因为thishow a function is called完全确定,而不是在那里的定义)。 jQuery并不使用this来引用它自己(通常它使用this来引用DOM元素,有时引用数组元素之类的其他东西;当引用自身时,因为它是单一的东西,它只是使用jQuery)。现在

,你可能想确保你的功能have proper names(而我分配到bar上面的函数是匿名   —属性有一个名称,但功能没有)。在这种情况下,你可能会到模块模式:

var foo = (function() { 
    function foo() { 
     alert("Foo!"); 
    } 

    function foo_bar() { 
     alert("Bar!"); 
    } 

    foo.bar = foo_bar; 

    return foo; 
})(); 

foo();  // "Foo!" 
foo.bar(); // "Bar!" 

这种模式还具有的优点是你可以有作用域功能(即包一切的大匿名函数)内举行的私人数据和功能,只有你的代码可以使用。

var foo = (function() { 
    function foo() { 
     reallyPrivate("Foo!"); 
    } 

    function foo_bar() { 
     reallyPrivate("Bar!"); 
    } 

    function reallyPrivate(msg) { 
     alert(msg); 
    } 

    foo.bar = foo_bar; 

    return foo; 
})(); 

foo();    // "Foo!" 
foo.bar();   // "Bar!" 
reallyPrivate("Hi"); // Error, `reallyPrivate` is undefined outside of the scoping function 

在代码中,你要指定的东西函数的prototype财产。当函数被称为构造函数(例如,通过new)时,该功能才起作用。当你这样做时,由new创建的对象接收函数的prototype属性作为其基础原型。但这是完全不同的事情,与jQuery所做的无关,它既是一个函数,也是的伪命名空间。

+1

打我给它。这里的所有都是它的!关于最后一点,下面是一篇关于使用带有或不带'new'的函数构造函数的文章,http://js-bits.blogspot.com/2010/08/constructors-without-using-new.html,因为jQuery可以工作像工厂一样。 – 2012-02-10 16:43:39

+0

所以我可以得到我想要的行为,而不必使用jQuery的原型魔法。这使事情变得更容易。感谢分享! – underscorePez 2012-02-13 09:19:13

2

你不需要任何古怪的,使用这样的东西。每个$你 只是附加功能函数对象的原型对象,而不是 :

function Constructor() { 
    if (!(this instanceof Constructor)) { 
     return new Constructor(); 
    } 
} 

Constructor.prototype = { 

    each: function() { 
     return "instance method"; 
    } 

}; 

Constructor.each = function() { 
    return "static method"; 
}; 


var a = Constructor(); 

a.each(); //"instance method" 
Constructor.each(); //"static method" 
+0

如何将Constructor.fn.function添加到实例函数中? – pie6k 2014-03-17 11:33:57

+0

@ Kluska000'Constructor.prototype.each = Constructor.each;'例如 – Esailija 2014-03-17 12:11:55