Que signifie jQuery.fn?

569

Que signifie fnici?

jQuery.fn.jquery
ajsie
la source

Réponses:

848

Dans jQuery, la fnpropriété n'est qu'un alias de la prototypepropriété.

L' jQueryidentifiant (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"
CMS
la source
4
Est-ce que cela est garanti? Puis-je supposer qu'un appel à jQuery.prototype est exactement le même que jQuery.fn? Mon inquiétude est que si jQuery fait de la magie lorsque vous appelez .fn, ils ne sont pas interchangeables
Brandon
4
Oh, il me manque quelque chose .. 'window.foo = foo' donne à 'foo' une portée globale? jamais nouveau, j'ajouterai cela à ma liste de techniques à apprendre.
EE33
2
@ EE33 Si je ne me trompe pas, la portée globale en javascript signifie simplement que votre variable est un paramètre de l'objet window.
Shawn
1
@Imray - return thispour permettre le chaînage , vous pouvez donc le fairefoo("bar").myPlugin().otherPlugin()
Racing Tadpole
3
@ Shawn Je pense que ce serait appelé une propriété, pas un paramètre, non? Un paramètre serait la variable «a» ici function func1 (a) { ... }, et une propriété serait la variable «a» ici var foo = {}; foo.a = 'a'.
Zack
145

jQuery.fnest défini en raccourci pour jQuery.prototype. Du code source :

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

Cela signifie qu'il jQuery.fn.jquerys'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",
Andy E
la source
15
J'aime cette réponse. Je montre exactement comment trouver la définition à l'intérieur du code source, puis comment interpréter la définition de manière utile. Le bon vieux "apprendre à l'homme à pêcher" méthode de réponse. +1.
EE33
mais quel est le but de faire cela? juste sauver quelques touches?
slier
@slier: oui, à peu près.
Andy E
je parie qu'il y a un autre but ... attacher la fonction à $ .fn, fera de la fonction statique
facile le
145

fnse 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 fnest sa disponibilité pour connecter vos propres fonctionnalités à jQuery. N'oubliez pas que jquery sera la portée parent de votre fonction, donc thisse 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.

Travis J
la source
11
Ne pouvez-vous pas simplement ignorer le eachdans 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.
SoonDead
6
@SoonDead - Vous pourriez certainement le faire parce que si l'objet jQuery contient une collection, la cssfonction les parcourra automatiquement en interne avec chacune. C'était juste un exemple de montrer les différences dans thislesquelles l'extérieur est l'objet jquery et l'intérieur fait référence à l'élément lui-même.
Travis J
1
@SoonDead Bon commentaire, mais j'aime vraiment la façon dont Travis J a expliqué l'idée / le principe. :)
Sander
5
C'est le meilleur commentaire - Savoir que fn n'est qu'un alias n'est pas aussi utile que de savoir pourquoi quelqu'un devrait s'en soucier, et cette réponse l'a magnifiquement démontré.
Gerard ONeill
1
Après avoir parcouru les autres réponses, j'ai trouvé que celle-ci était plus facile à comprendre le concept principal. Je vous remercie. :)
VivekP
0

Dans le code source jQuery que nous avons jQuery.fn = jQuery.prototype = {...}depuis jQuery.prototypeest un objet dont la valeur jQuery.fnsera simplement une référence au même objet qui fait jQuery.prototypedéjà référence.

Pour confirmer cela, vous pouvez vérifier jQuery.fn === jQuery.prototypesi cela évalue true(ce qu'il fait) puis ils référencent le même objet

Yehuda Schwartz
la source