为什么jQuery构造函数映射到jQuery.fn.init? [英] Why does the jQuery constructor map to jQuery.fn.init?

查看:157
本文介绍了为什么jQuery构造函数映射到jQuery.fn.init?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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

我想知道为什么。



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



这个问题仍然没有答案



这仅仅是出于组织目的吗?作者可能希望打包它,而不是将init函数放在jQuery构造函数定义中。



是否有理由在原型上使用 .init()方法?我认为没有人使用 $('。something')... init()...



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



我刚刚找到

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




  • 关闭中的任何地方

  • jQuery 对象( jQuery.init vs jQuery.fn.init

  • 或者,对我来说最有意义的是:直接在 jQuery 函数/构造函数定义中,替换 new jQuery.fn.init 并避免 jQu ery.fn.init.prototype = jQuery.fn mapping。


解决方案


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){
//构造函数逻辑
};

//允许语法糖
jQuery.fn = jQuery.Set.prototype = {
构造函数:jQuery.Set,
//方法
} ;

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


  1. jQuery 是用于创建 jQuery.Set 对象的工厂函数。

  2. jQuery.fn 仅作为语法糖存在,而不是必须一直编写 jQuery.Set.prototype 来修改原型。

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

  jQuery.fn = jQuery.prototype = {
构造函数:jQuery

其中一个原因当然是他们希望容纳可能会修改的人 jQuery.prototype 而不是 jQuery.fn



然而另一个有效的rea儿子是他们可能希望 somejQueryObj instanceof jQuery 返回true,而通常不会。如果你采用上面的模式(使用jQuery.Set),你会注意到:

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

但是如果我们设置原型 jQuery jQuery.Set.prototype ,让我们看看会发生什么。

  jQuery.prototype = jQuery.Set.prototype; 
jQuery()instanceof jQuery; //真正!

要理解那些导致这些设计决策的东西并不是很容易点,但对我而言,他们的设计似乎过于复杂。


The jQuery constructor sort of maps its functionality to another constructor, jQuery.fn.init:

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

I'm wondering why.

This question is very similar, but even the answerer admits they didn't really answer the question as to why

This question is still unanswered

Is this just for organizational purposes? Rather than putting the init function inside the jQuery constructor definition, maybe the authors wanted to package it.

Is there any reason to have the .init() method on the prototype? I don't think anyone ever uses $('.something')...init()...

This question shows that its not necessary to have .init on the prototype.

And I just found this question in which Dan Herbert's answer suggests that it is simply for structure/readability purposes.

In conclusion, can I confirm that this constructor/prototype mapping funny-business is kind of unnecessary? It seems to me that the jQuery.fn.init functionality could go:

  • Anywhere in the closure
  • On the jQuery object (jQuery.init vs jQuery.fn.init)
  • Or, what makes most sense to me: directly inside the jQuery function/constructor definition, replacing new jQuery.fn.init and avoiding the jQuery.fn.init.prototype = jQuery.fn mapping.

解决方案

The jQuery constructor sort of maps its functionality to another constructor

The fact is that jQuery is not really a constructor function and shouldn't be seen as one either. By definition, a constructor's responsability is to initialize instance properties, which is not really the case with jQuery. Also, calling new jQuery() would be non-sense. jQuery is a factory function for creating jQuery.fn.init instances, nothing more.

Now, perhaps you are wondering why they simply didin't use jQuery as a real constructor?

Well because they did not want a constructor that we call with new all the time, they wanted a factory function. That's fine with me, however where I tend to disagree is that their pattern is very cryptic and doesn't quite reflect the intention.

It would have been far better in my opinion to chose better names:

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

I've pretty much only remapped jQuery.fn.init to jQuery.Set and it suddenly all makes more sense to me. When looking at the code above, it's easy to see that:

  1. jQuery is a factory function for creating jQuery.Set objects.
  2. jQuery.fn exists only as a syntaxic sugar, instead of having to write jQuery.Set.prototype all the time to modify the prototype.

Now, in the source we also see that they do the following, which is kinda non-sense since jQuery is not the real constructor, it's jQuery.prototype.init and since we aren't creating jQuery instances, setting jQuery.prototype seems useless:

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

One of the reasons behind this is certainly that they want to accomodate people that might modify jQuery.prototype instead of jQuery.fn.

However another valid reason is that they perhaps wanted somejQueryObj instanceof jQuery to returns true, while it normally wouldn't. If you take the pattern above (with jQuery.Set) you will notice that:

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

However if we set the prototype of jQuery to jQuery.Set.prototype, let's see what happens.

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

It's not easy to understand eveything that led to those design decisions and perhaps I am missing important points, but to me it seems their design is overcomplicated.

这篇关于为什么jQuery构造函数映射到jQuery.fn.init?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆