为什么jQuery这样做:jQuery.fn.init.prototype = jQuery.fn?

20

稍微延伸一下的问题是为什么要使用 jQuery?

jQuery.fn = jQuery.prototype = {
init: function() {...},
    f1: function() {...},
    ...
};
jQuery.fn.init.prototype = jQuery.fn;

为什么不直接将f1()等函数添加到init.prototype中呢?这只是外观上的问题吗,还是有一些深层次的想法呢?


我不确定您所说的将f1()添加到init.prototype中是什么意思?它并没有添加到任何地方,而是将原型赋值。 - Milan Babuškov
当然,我的意思是“赋值”。对不起我的英语。问题是为什么不直接将所有函数分配给init.prototype?为什么要将它们分配给jQuery.prototype,然后再将jQuery.prototype分配给jQuery.prototype.init.prototype? - NilColor
关于jQuery的设计模式的相关问题:https://dev59.com/hGfWa4cB1Zd3GeqPj72m - Bergi
2个回答

47

jQuery.fn.init 函数是在你调用 jQuery(".some-selector") 或者 $(".some-selector") 时被执行的函数。你可以在这个从 jquery.js 中提取的代码片段中看到:

jQuery = window.jQuery = window.$ = function( selector, context ) {
    // The jQuery object is actually just the init constructor 'enhanced'
    return new jQuery.fn.init( selector, context );
}

事实上,您提到的代码行对于jQuery允许在jQuery对象内部和插件中添加功能至关重要。这是代码行:

jQuery.fn.init.prototype = jQuery.fn;

通过将jQuery.fn赋值为此函数的原型(并且因为第一个代码片段使用'new'将jQuery.fn.init视为构造函数),这意味着通过jQuery.fn.whatever添加的功能立即可用于所有jQuery调用返回的对象。

因此,例如,可以像这样创建和使用简单的jQuery插件:

jQuery.fn.foo = function () { alert("foo!"); };
jQuery(".some-selector").foo();

当你在第一行声明 'jQuery.fn.foo' 时,实际上是将该函数添加到使用 jQuery 函数创建的所有 jQuery 对象的原型中,就像第二行中的对象一样。这使得你可以简单地对 jQuery 函数的结果调用 'foo()' 并调用你的插件函数。

简而言之,如果在 jQuery 中不存在这行代码,则编写 jQuery 插件将更加冗长且容易受到未来更改的影响。


这是我读过的最有启发性的评论。谢谢。 - asumaran
抱歉在回答/评论中插入一个问题,但我们是否在说以这种方式向jQuery添加函数会使该函数对页面上的每个元素都可用?它是否使该函数对元素以外的其他东西(如其他jQuery对象等)也可用?而且,“jQuery = window.jQuery = window.$ = function(...”只是一种显示所有三个等效语法的方式吗?还是这实际上是您要做的事情? - KWallace

21

jQuery.fn只是jQuery.prototype的别名。我想它是出于美观和减少输入的原因而定义的。

所以

jQuery.fn.init.prototype = jQuery.fn;

实际上是

jQuery.prototype.init.prototype = jQuery.prototype;

为什么需要这样做,这个论坛帖子很有帮助:

它给init()函数设置了与jQuery对象相同的原型。因此,在“return new jQuery.fn.init(selector, context);”语句中将init()作为构造函数调用时,它使用该原型来构造对象。这使得init()可以替代jQuery构造函数本身。

这样做的目的是从jQuery.fn.init构造函数返回的对象可以访问jQuery方法。


是的,我知道.fn.prototype的快捷方式。 但为什么他们扩展jQuery.prototype并执行jQuery.fn.init.prototype = jQuery.fn?为什么不直接扩展jQuery.fn.init.prototype呢? - NilColor

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接