2 回答
TA贡献1836条经验 获得超4个赞
我也不喜欢这种模式。他们有一个init
函数,它是所有jQuery实例的构造jQuery
函数-该函数本身只是对象创建过程的包装器new
:
function jQuery(…) { return new init(…); }
然后,他们将这些实例的方法添加到init.prototype
对象中。该对象作为接口公开jQuery.fn
。另外,他们将prototype
jQuery函数的属性设置为该对象-对于不使用该fn
属性的用户。现在你有
jQuery.prototype = jQuery.fn = […]init.prototype
但是他们也做两件事:
覆盖
constructor
原型对象的属性,将其设置为jQuery
函数公开
init
功能jQuery.fn
-自己的原型。这可能允许扩展$ .fn.init函数,但非常令人困惑
我认为他们需要/想要做所有这些事情以防万一,但是他们的代码是一团糟-从该对象文字开始,然后分配初始化原型。
TA贡献1815条经验 获得超6个赞
如果将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提到的以外,还有其他一些奇怪之处:
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); // trueconsole.log( new a instanceof b); // true
旁注:我个人使用了以下构造函数模式,结果相似但没有怪异:
var a = function(arg) { if (!(this instanceof a)) { return new a(arg); }};a.prototype.method = function(){ return this; };
添加回答
举报