jQuery样式的函数,可以像对象一样访问

时间:2012-02-10 16:31:26

标签: javascript jquery

我正在为Web服务创建一个AJAX API,我希望能够调用类似jQuery的访问器。 jQuery似乎能够将'jQuery'作为一个函数执行,但也可以用它来直接访问函数EG的结果对象:

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

我确定我错过了一些简单的事情:(

2 个答案:

答案 0 :(得分:5)

jQuery正在做的是使用jQuery作为函数和伪命名空间。也就是说,您可以调用 jQueryvar divs = jQuery("div"); 您可以使用其中的属性,例如:jQuery.each(...);

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

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

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

这就是它的全部内容。

bar的来电中,this将成为foo函数(因为this完全由how a function is called决定,而不是由this确定。 jQuery不使用this来引用它自己(通常它使用jQuery来引用DOM元素,有时候引用其他东西,比如数组元素;当引用它自己时,因为它是单一的东西,它只是使用bar)。

现在,您可能希望确保您的函数have proper names(而我上面分配给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创建的对象将接收函数的{{1}}属性作为其基础原型。但这是一个完全不同的事情,与jQuery所做的无关,它既是函数又是伪命名空间。

答案 1 :(得分:2)

你不需要任何奇怪的东西,使用像$ .each这样的东西 您只需将函数附加到函数对象 原型对象:

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"
相关问题