Réponses:
Dans jQuery, la fn
propriété n'est qu'un alias de la prototype
propriété.
L' jQuery
identifiant (ou $
) n'est qu'une fonction constructeur , et toutes les instances créées avec lui, héritent du prototype du constructeur.
Une fonction constructeur simple:
function Test() {
this.a = 'a';
}
Test.prototype.b = 'b';
var test = new Test();
test.a; // "a", own property
test.b; // "b", inherited property
Une structure simple qui ressemble à l'architecture de 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
pour permettre le chaînage , vous pouvez donc le fairefoo("bar").myPlugin().otherPlugin()
function func1 (a) { ... }
, et une propriété serait la variable «a» ici var foo = {}; foo.a = 'a'
.
jQuery.fn
est défini en raccourci pour jQuery.prototype
. Du code source :
jQuery.fn = jQuery.prototype = {
// ...
}
Cela signifie qu'il jQuery.fn.jquery
s'agit d'un alias pour jQuery.prototype.jquery
, qui renvoie la version actuelle de jQuery. Encore une fois à partir du code source :
// The current version of jQuery being used
jquery: "@VERSION",
fn
se réfère littéralement à la jquery prototype
.
Cette ligne de code est dans le code source:
jQuery.fn = jQuery.prototype = {
//list of functions available to the jQuery api
}
Mais le véritable outil derrière fn
est sa disponibilité pour connecter vos propres fonctionnalités à jQuery. N'oubliez pas que jquery sera la portée parent de votre fonction, donc this
se référera à l'objet jquery.
$.fn.myExtension = function(){
var currentjQueryObject = this;
//work with currentObject
return this;//you can include this if you would like to support chaining
};
Voici donc un exemple simple de cela. Disons que je veux faire deux extensions, une qui met une bordure bleue et qui colore le texte en bleu, et je veux les enchaîner.
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;
};
Vous pouvez maintenant les utiliser contre une classe comme celle-ci:
$('.blue').blueBorder().blueText();
(Je sais que cela est mieux fait avec CSS comme l'application de noms de classe différents, mais s'il vous plaît gardez à l'esprit que ce n'est qu'une démo pour montrer le concept)
Cette réponse a un bon exemple d'une extension à part entière.
each
dans votre exemple de code? $.fn.blueBorder = function(){ this.css("border","solid blue 2px"); return this; };
fonctionnerait bien, car .css()
alerady itère sur les éléments.
css
fonction les parcourra automatiquement en interne avec chacune. C'était juste un exemple de montrer les différences dans this
lesquelles l'extérieur est l'objet jquery et l'intérieur fait référence à l'élément lui-même.
Dans le code source jQuery que nous avons jQuery.fn = jQuery.prototype = {...}
depuis jQuery.prototype
est un objet dont la valeur jQuery.fn
sera simplement une référence au même objet qui fait jQuery.prototype
déjà référence.
Pour confirmer cela, vous pouvez vérifier jQuery.fn === jQuery.prototype
si cela évalue true
(ce qu'il fait) puis ils référencent le même objet