Cosa significa jQuery.fn?


Risposte:


848

In jQuery, la fnproprietà è solo un alias della prototypeproprietà.

L' jQueryidentificatore (o $) è solo una funzione del costruttore e tutte le istanze create con esso ereditano dal prototipo del costruttore.

Una semplice funzione di costruzione:

function Test() {
  this.a = 'a';
}
Test.prototype.b = 'b';

var test = new Test(); 
test.a; // "a", own property
test.b; // "b", inherited property

Una struttura semplice che ricorda l'architettura di jQuery:

(function() {
  var foo = function(arg) { // core constructor
    // ensure to use the `new` operator
    if (!(this instanceof foo))
      return new foo(arg);
    // store an argument for this example
    this.myArg = arg;
    //..
  };

  // create `fn` alias to `prototype` property
  foo.fn = foo.prototype = {
    init: function () {/*...*/}
    //...
  };

  // expose the library
  window.foo = foo;
})();

// Extension:

foo.fn.myPlugin = function () {
  alert(this.myArg);
  return this; // return `this` for chainability
};

foo("bar").myPlugin(); // alerts "bar"

4
Questo è garantito per essere vero? Posso assumere una chiamata a jQuery.prototype è esattamente uguale a jQuery.fn? La mia preoccupazione è se jQuery fa un po 'di magia quando chiami .fn, allora non sono intercambiabili
Brandon

4
Oh, mi manca qualcosa .. 'window.foo = foo' dà a 'foo' un ambito globale? mai nuovo, lo aggiungerò al mio elenco di tecniche da imparare.
EE33

2
@ EE33 Se non sbaglio, l'ambito globale in JavaScript significa semplicemente che la tua variabile è un parametro dell'oggetto finestra.
Shawn,

1
@Imray - return thisper consentire il concatenamento , quindi potresti farefoo("bar").myPlugin().otherPlugin()
Racing Tadpole,

3
@Shawn Penso che sarebbe chiamato una proprietà, non un parametro, giusto? Un parametro sarebbe la variabile 'a' qui function func1 (a) { ... }, e una proprietà sarebbe la variabile 'a' qui var foo = {}; foo.a = 'a'.
Zack,

145

jQuery.fnè definito scorciatoia per jQuery.prototype. Dal codice sorgente :

jQuery.fn = jQuery.prototype = {
    // ...
}

Ciò significa che jQuery.fn.jqueryè un alias per jQuery.prototype.jquery, che restituisce la versione corrente di jQuery. Ancora dal codice sorgente :

// The current version of jQuery being used
jquery: "@VERSION",

15
Mi piace questa risposta. Mostrerò esattamente come trovare la definizione all'interno del codice sorgente e come interpretare la definizione in modo utile. Il buon vecchio "insegna a un uomo a pescare" il metodo di risposta. +1.
EE33

ma qual è lo scopo di farlo? stai solo salvando un paio di battute?
slier

@slier: sì, praticamente.
Andy E

Scommetto che c'è un altro scopo..attaccando la funzione a $ .fn, renderà la funzione statica
Slier

145

fnsi riferisce letteralmente al jquery prototype.

Questa riga di codice è nel codice sorgente:

jQuery.fn = jQuery.prototype = {
 //list of functions available to the jQuery api
}

Ma il vero strumento alla base fnè la sua disponibilità ad agganciare la tua funzionalità a jQuery. Ricorda che jquery sarà l'ambito genitore della tua funzione, quindi thisfarà riferimento all'oggetto jquery.

$.fn.myExtension = function(){
 var currentjQueryObject = this;
 //work with currentObject
 return this;//you can include this if you would like to support chaining
};

Quindi ecco un semplice esempio di questo. Diciamo che voglio fare due estensioni, una che mette un bordo blu e che colora il testo in blu e le voglio incatenate.

jsFiddle Demo

$.fn.blueBorder = function(){
 this.each(function(){
  $(this).css("border","solid blue 2px");
 });
 return this;
};
$.fn.blueText = function(){
 this.each(function(){
  $(this).css("color","blue");
 });
 return this;
};

Ora puoi usarli contro una classe come questa:

$('.blue').blueBorder().blueText();

(So ​​che è meglio farlo con css come applicare nomi di classe diversi, ma tieni presente che questa è solo una demo per mostrare il concetto)

Questa risposta ha un buon esempio di estensione completa.


11
Non puoi semplicemente saltare il eachnel tuo codice di esempio? $.fn.blueBorder = function(){ this.css("border","solid blue 2px"); return this; };funzionerebbe benissimo, poiché .css()alerady scorre gli elementi.
Presto morirà

6
@SoonDead - Potresti sicuramente perché se l'oggetto jQuery contiene una raccolta, la cssfunzione eseguirà l'iterazione automatica su di essi internamente con ciascuno. Era solo un esempio di mostrare le differenze in thiscui quello esterno è l'oggetto jquery e quello interno fa riferimento all'elemento stesso.
Travis J,

1
@SoonDead Buon commento, ma mi piace molto come Travis J abbia spiegato l'idea / principio. :)
Sander,

5
Questo è il miglior commento - Sapere che fn è solo un alias non è utile quanto sapere perché qualcuno dovrebbe interessarsene, e questa risposta lo ha dimostrato magnificamente.
Gerard ONeill,

1
Dopo aver esaminato le altre risposte, ho trovato questo più facile da capire il concetto principale. Grazie. :)
VivekP,

0

Nel codice sorgente di jQuery abbiamo jQuery.fn = jQuery.prototype = {...}poiché jQuery.prototypeè un oggetto il cui valore jQuery.fnsarà semplicemente un riferimento allo stesso oggetto che jQuery.prototypegià fa riferimento.

Per confermare ciò è possibile verificare jQuery.fn === jQuery.prototypeche valuti true(cosa che fa), quindi fanno riferimento allo stesso oggetto

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.