6

构造函数将jQuery其功能映射到另一个构造函数,jQuery.fn.init

jQuery = function( selector, context ) {
    return new jQuery.fn.init( selector, context, rootjQuery );
},

我想知道为什么。

这个问题非常相似,但即使是回答者也承认他们并没有真正回答这个问题,为什么

这个问题仍然没有答案

这只是出于组织目的吗?与其将 init 函数放在 jQuery 构造函数定义中,也许作者想将其打包。

有什么理由.init()在原型上使用该方法吗? 我认为没有人使用过$('.something')...init()...

这个问题表明它没有必要.init在原型上。

我刚刚发现这个问题Dan Herbert 的回答表明它只是出于结构/可读性的目的。

总之,我可以确认这个构造函数/原型映射有趣的业务是不必要的吗? 在我看来,jQuery.fn.init功能可以去:

  • 在封闭的任何地方
  • jQuery对象上(jQuery.initvs jQuery.fn.init
  • 或者,对我来说最有意义的是:直接在jQuery函数/构造函数定义中,替换new jQuery.fn.init和避免jQuery.fn.init.prototype = jQuery.fn映射。
4

2 回答 2

4

jQuery 构造函数将其功能映射到另一个构造函数

事实上,jQuery它并不是真正的构造函数,也不应该被视为一个构造函数。根据定义,构造函数的职责是初始化实例属性,而jQuery. 此外,打电话new jQuery()是无意义的。jQuery是用于创建jQuery.fn.init实例的工厂函数,仅此而已

现在,也许您想知道为什么它们根本没有jQuery用作真正的构造函数?

好吧,因为他们不想要我们new一直调用的构造函数,所以他们想要一个工厂函数。这对我来说很好,但我倾向于不同意的是他们的模式非常神秘,并不能完全反映意图

在我看来,选择更好的名字会好得多:

function jQuery(selector, context) {
    return new jQuery.Set(selector, context);
}

jQuery.Set = function (selector, context) {
    //constructor logic
};

//allows syntaxic sugar
jQuery.fn = jQuery.Set.prototype = {
    constructor: jQuery.Set,
    //methods
};

我几乎只是重新映射jQuery.fn.initjQuery.Set它突然对我来说更有意义了。查看上面的代码时,很容易看出:

  1. jQuery是用于创建jQuery.Set对象的工厂函数。
  2. jQuery.fn仅作为语法糖存在,而不必一直编写jQuery.Set.prototype来修改原型。

现在,在源代码中,我们还看到它们执行以下操作,这有点荒谬,因为jQuery它不是真正的构造函数,jQuery.prototype.init而且因为我们没有创建jQuery实例,所以设置jQuery.prototype似乎没用:

jQuery.fn = jQuery.prototype = {
      constructor: jQuery

这背后的原因之一当然是他们想要容纳可能会修改jQuery.prototype而不是jQuery.fn.

然而,另一个正当的理由是他们可能想要somejQueryObj instanceof jQuery返回 true,而通常不会。如果您采用上面的模式(使用 jQuery.Set),您会注意到:

jQuery() instanceof jQuery; //false
jQuery() instanceof jQuery.Set; //true

但是,如果我们将prototypeof设置jQueryjQuery.Set.prototype,让我们看看会发生什么。

jQuery.prototype = jQuery.Set.prototype;
jQuery() instanceof jQuery; //true!

理解导致这些设计决策的所有事情并不容易,也许我错过了重要的点,但对我来说,他们的设计似乎过于复杂。

于 2013-11-03T23:27:35.920 回答
-1

它允许您链接构造函数。有点儿...

所以而不是

$('.someClass').hide();
$('.someOtherClass').hide();

你可以做

$('.someClass').hide().init.call($.fn, '.someOtherClass').hide();

这行得通,但它也是一个笑话。

于 2013-11-03T22:42:38.283 回答