2012-08-27 11 views
5

¡Bien! En primer lugar, esta pregunta viene de un hombre que cava demasiado profundo (y posiblemente se pierde) en el universo jQuery.Diferencia del valor, prototipo y propiedad

En mi reserch descubrí el patrón principal de la jQuery es algo como esto (Si se wellcomed corrección necesaria):

(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() {} 

     }) 

     }) 

Cuando $ inicia la jQuery.prototype.init iniciados y devuelve una matriz de elementos. Pero no pude entender cómo se agrega el método jQuery como .css o .hide, etc. a esta matriz

obtengo los métodos estáticos. Pero no pude ver cómo regresa y la matriz de elementos con todos esos métodos.

+0

Gracias @adnan para la edición – Lupus

Respuesta

8

No me gusta ese patrón tampoco. Tienen una función init, que es el constructor de todas las instancias de jQuery - la función jQuery en sí es sólo un envoltorio en torno a que la creación de objetos con new:

function jQuery(…) { return new init(…); } 

A continuación, se suman los métodos de esos casos al objeto init.prototype . Este objeto está expuesto como una interfaz en jQuery.fn. Además, establecen la propiedad prototype de la función jQuery en ese objeto, para aquellos que no usan la propiedad fn. Ahora usted tiene

jQuery.prototype = jQuery.fn = […]init.prototype 

Pero también hace dos [raras] cosas:

  • sobrescribir la propiedad constructor del objeto prototipo, poniéndolo a la función jQuery
  • exponer la función init en jQuery.fn - su propio prototipo. Esto podría permitir Extending $.fn.init function, pero es muy confuso

Creo que necesitan/quieren hacer que todo esto sea a prueba de tontos, pero su código es un desastre - empezando por el objeto literal y la asignación de las cosas prototipo init después .

+1

1 por despreciar este patrón – Adi

+0

¿Está sobreescribiendo el constructor cómo obtienen 'this', es decir, el valor devuelto para apuntar a jQuery? ... no, esto es para lo # 2 extraño para lo que es # 1 cosa extraña ¿para? –

+0

esto es esencialmente un truco para obtener inits 'this' para parecerse a un jQuery' this' –

3

Es más fácil de digerir si piensa en la API como una colección de métodos externos, y la función jQuery es la envoltura.

Es básicamente construido como esto:

function a() { return new b();} 
a.prototype.method = function() { return this; } 
function b() {} 
b.prototype = a.prototype; 

Excepto que a es jQuery y b es jQuery.prototype.init.

Estoy seguro de que Resig tenía sus razones para colocar el constructor de API en el prototipo init, pero no puedo verlas.Una pareja de más extrañeza además de los Bergi mencionó:

1) Los patrones requiere una copia de referencia jQuery.fn.init.prototype-jQuery.prototype, cosa que permite que un extraño bucle sin fin:

var $body = new $.fn.init.prototype.init.prototype.init.prototype.init('body'); 

2) Cada colección de jQuery es en realidad una instancia de jQuery.fn.init, pero como hacen referencia al mismo objeto prototipo, nos engaña para "pensar" que la colección es una instancia de jQuery. Puede hacer lo mismo hechicería como esto:

function a(){} 
function b(){} 
a.prototype = b.prototype; 
console.log(new b instanceof a); // true 
console.log(new a instanceof b); // true 

Nota al margen: Yo personalmente he utilizado el siguiente patrón constructor con resultados similares sin la rareza:

var a = function(arg) { 
    if (!(this instanceof a)) { 
     return new a(arg); 
    } 
}; 
a.prototype.method = function(){ return this; }; 
Cuestiones relacionadas