为什么jQuery构造函数映射到jQuery.fn.init? [英] Why does the jQuery constructor map to 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
vsjQuery.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
它突然对我来说更有意义。查看上面的代码时,很容易看出:
-
jQuery
是用于创建jQuery.Set
对象的工厂函数。 -
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 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
vsjQuery.fn.init
) - Or, what makes most sense to me: directly inside the
jQuery
function/constructor definition, replacingnew jQuery.fn.init
and avoiding thejQuery.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:
jQuery
is a factory function for creatingjQuery.Set
objects.jQuery.fn
exists only as a syntaxic sugar, instead of having to writejQuery.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屋!