OK!首先,这个问题来自于一个在jQuery世界中挖得太深(并且可能会迷路)的人。
在我的研究中,我发现jquery的主要模式是这样的(如果需要更正是好的):
(function (window, undefined) {
jQuery = function (arg) {
// The jQuery object is actually just the init constructor 'enhanced'
return new jQuery.fn.init(arg);
},
jQuery.fn = jQuery.prototype = {
constructor: jQuery,
init: function (selector, context, rootjQuery) {
// get the selected DOM el.
// and returns an array
},
method: function () {
doSomeThing();
return this;
},
method2: function () {
doSomeThing();
return this;,
method3: function () {
doSomeThing();
return this;
};
jQuery.fn.init.prototype = jQuery.fn;
jQuery.extend = jQuery.fn.extend = function () {
//defines the extend method
};
// extends the jQuery function and adds some static methods
jQuery.extend({
method: function () {}
})
})
当$
启动jQuery.prototype.init
启动并返回一个元素数组时。但我无法理解它是如何添加jQuery方法的,如.css
或.hide
等。到这个数组。
我得到了静态方法。但无法通过所有这些方法获得它返回的元素和元素数组。
答案 0 :(得分:8)
我也不喜欢那种模式。它们有一个init
函数,它是所有jQuery实例的构造函数 - jQuery
函数本身只是使用new
创建对象的包装器:
function jQuery(…) { return new init(…); }
然后,他们将这些实例的方法添加到init.prototype
对象。此对象在jQuery.fn
处作为接口公开。此外,他们将jQuery函数的prototype
属性设置为该对象 - 对于那些不使用fn
属性的人。现在你有了
jQuery.prototype = jQuery.fn = […]init.prototype
但他们也做了两件事[奇怪]:
constructor
属性,将其设置为jQuery
函数init
上展示jQuery.fn
函数 - 它自己的原型。这可能允许Extending $.fn.init function,但非常令人困惑我认为他们需要/想要做所有这些都是万无一失的,但他们的代码是一团糟 - 从该对象文字开始并随后分配init原型。
答案 1 :(得分:3)
如果您将API视为外部方法集合,并将jQuery函数视为包装器,则更容易理解。
它的基本构造如下:
function a() { return new b();}
a.prototype.method = function() { return this; }
function b() {}
b.prototype = a.prototype;
a
为jQuery
且b
为jQuery.prototype.init
。
我确定Resig有他的原因将api构造函数放在init原型中,但我看不到它们。除了Bergi提到的一些奇怪之处:</ p>
1)模式需要从jQuery.fn.init.prototype
到jQuery.prototype
的参考副本,它允许一个奇怪的无限循环:
var $body = new $.fn.init.prototype.init.prototype.init.prototype.init('body');
2)每个jQuery集合实际上都是jQuery.fn.init
的一个实例,但由于它们引用了相同的原型对象,因此它诱使我们“认为”该集合是jQuery
的一个实例。你可以这样做同样的巫术:
function a(){}
function b(){}
a.prototype = b.prototype;
console.log( new b instanceof a); // true
console.log( new a instanceof b); // true
旁注:我个人使用了以下构造函数模式,但结果并不奇怪:
var a = function(arg) {
if (!(this instanceof a)) {
return new a(arg);
}
};
a.prototype.method = function(){ return this; };