Risposte:
In jQuery, la fn
proprietà è solo un alias della prototype
proprietà.
L' jQuery
identificatore (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"
return this
per consentire il concatenamento , quindi potresti farefoo("bar").myPlugin().otherPlugin()
function func1 (a) { ... }
, e una proprietà sarebbe la variabile 'a' qui var foo = {}; foo.a = 'a'
.
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",
fn
si 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 this
farà 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.
each
nel tuo codice di esempio? $.fn.blueBorder = function(){ this.css("border","solid blue 2px"); return this; };
funzionerebbe benissimo, poiché .css()
alerady scorre gli elementi.
css
funzione eseguirà l'iterazione automatica su di essi internamente con ciascuno. Era solo un esempio di mostrare le differenze in this
cui quello esterno è l'oggetto jquery e quello interno fa riferimento all'elemento stesso.
Nel codice sorgente di jQuery abbiamo jQuery.fn = jQuery.prototype = {...}
poiché jQuery.prototype
è un oggetto il cui valore jQuery.fn
sarà semplicemente un riferimento allo stesso oggetto che jQuery.prototype
già fa riferimento.
Per confermare ciò è possibile verificare jQuery.fn === jQuery.prototype
che valuti true
(cosa che fa), quindi fanno riferimento allo stesso oggetto