价值,原型和财产的差异
好! 首先,这个问题来自一个在jQuery世界中挖掘得太深(而且可能会迷路)的人。
在我的研究中,我发现jquery的主要模式是这样的(如果需要更正wellcomed):
(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
启动并返回一组元素。 但我不明白它是如何添加像.css
或.hide
等jQuery方法。 到这个数组。
我得到的静态方法。 但无法得到它如何返回和所有这些方法的元素数组。
我也不喜欢那种模式。 他们有一个init
函数,它是所有jQuery实例的构造函数 – jQuery
函数本身仅仅是用new
对象来创build对象:
function jQuery(…) { return new init(…); }
然后,他们将这些实例的方法添加到init.prototype
对象中。 该对象在jQuery.fn
作为接口公开。 另外,他们将jQuery函数的prototype
属性设置为该对象 – 对于那些不使用fn
属性的人。 现在你有
jQuery.prototype = jQuery.fn = […]init.prototype
但是他们也做了两件怪事:
- 覆盖原型对象的
constructor
属性,将其设置为jQuery
函数 - 公开
jQuery.fn
上的init
函数 – 它自己的原型。 这可能允许扩展$ .fn.init函数 ,但是非常混乱
我认为他们需要/想要做所有这些以防万一,但是他们的代码是一团糟 – 从对象文字开始,然后分配init原型。
如果将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); // 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; };