Risposte:
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"
return thisper 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",
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.
eachnel tuo codice di esempio? $.fn.blueBorder = function(){ this.css("border","solid blue 2px"); return this; };funzionerebbe benissimo, poiché .css()alerady scorre gli elementi.
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.
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