扩展的小问题是为什么 jQuery 这样做
jQuery.fn = jQuery.prototype = {
init: function() {...},
f1: function() {...},
...
};
jQuery.fn.init.prototype = jQuery.fn;
为什么不简单地将f1()
etc添加到init.prototype
?只是审美还是有一些深刻的想法?
扩展的小问题是为什么 jQuery 这样做
jQuery.fn = jQuery.prototype = {
init: function() {...},
f1: function() {...},
...
};
jQuery.fn.init.prototype = jQuery.fn;
为什么不简单地将f1()
etc添加到init.prototype
?只是审美还是有一些深刻的想法?
该函数jQuery.fn.init
是在您调用jQuery(".some-selector")
or时执行的函数$(".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 本身内部还是从插件中。这是线路:
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 插件会更加冗长,并且将来可能会损坏。
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 方法。