2012-08-27 7 views
5

OK! Prima di tutto questa domanda viene da un uomo che scava troppo in profondità (e si può eventualmente perdere) nell'universo jQuery.Differenza del valore, prototipo e proprietà

Nel mio Reserch ho scoperto modello principale del jquery è qualcosa di simile (Se la correzione necessaria è 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() {} 

     }) 

     }) 

Quando $ avvia la jQuery.prototype.init iniziati e restituisce un array di elementi. Ma non riuscivo a capire come aggiunge il metodo jQuery come .css o .hide, ecc. a questo array.

Ottengo i metodi statici. Ma non è possibile ottenere come restituisce e matrice di elementi con tutti quei metodi.

+0

thanx @adnan per la modifica – Lupus

risposta

8

Non mi piace neanche quello schema. Hanno una funzione init, che è il costruttore di tutte le istanze di jQuery - la funzione jQuery sé è solo un wrapper che la creazione di oggetti con new:

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

Poi, aggiungono i metodi di quelle istanze per l'oggetto init.prototype . Questo oggetto è esposto come interfaccia a jQuery.fn. Inoltre, impostano la proprietà prototype della funzione jQuery su quell'oggetto, per coloro che non utilizzano la proprietà fn. Ora avete

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

Ma hanno anche fatto due [strane] cose:

  • sovrascrivendo la proprietà constructor dell'oggetto prototipo, impostandolo al jQuery funzione di
  • esponendo la funzione init su jQuery.fn - il suo prototipo. Questo potrebbe consentire Extending $.fn.init function, ma è molto confuso

Credo che abbiano bisogno/voglia di fare tutto questo per essere infallibile, ma il loro codice è un pasticcio - a cominciare da quello letterale oggetto e assegnando le cose init prototipali in seguito .

+1

+1 per disprezzare questo modello – Adi

+0

Sovrascrive il costruttore come ottengono "questo", cioè il valore restituito a puntare a jQuery? ... no questo è ciò che è la cosa strana n. 2 per ... cosa è la cosa strana n. 1 per? –

+0

questo è essenzialmente un trucco per far sì che questo 'assomigli a un jQuery' questo' –

3

È più facile da digerire se si pensa all'API come una raccolta esterna di metodi e alla funzione jQuery come wrapper.

E 'fondamentalmente costruito in questo modo:

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

Solo che a è jQuery e b è jQuery.prototype.init.

Sono sicuro che Resig aveva le sue ragioni per posizionare il costruttore di api nel prototipo di init, ma non riesco a vederle.Un paio di più strangeness oltre a quelle Bergi menzionato:

1) I modelli richiede una copia di riferimento dal jQuery.fn.init.prototype a jQuery.prototype a scomparsa che permette un ciclo infinito strano:

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

2) Ogni collezione jQuery è in realtà un istanza di jQuery.fn.init, ma poiché fanno riferimento allo stesso oggetto prototipo, ci inducono a "pensare" che la raccolta sia un'istanza di jQuery. Si può fare la stessa stregoneria in questo modo:

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

Sidenote: Personalmente ho usato il seguente schema costruttore con risultati simili, senza la stranezza:

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