Was bedeutet jQuery.fn?

568

Was bedeutet das fnhier?

jQuery.fn.jquery
Ajsie
quelle

Antworten:

848

In jQuery ist die fnEigenschaft nur ein Alias ​​für die prototypeEigenschaft.

Der jQueryBezeichner (oder $) ist nur eine Konstruktorfunktion , und alle damit erstellten Instanzen erben vom Prototyp des Konstruktors.

Eine einfache Konstruktorfunktion:

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

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

Eine einfache Struktur, die der Architektur von jQuery ähnelt:

(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
quelle
4
Ist das garantiert wahr? Kann ich davon ausgehen, dass ein Aufruf von jQuery.prototype genau mit jQuery.fn identisch ist? Ich mache mir Sorgen, wenn jQuery etwas magisch macht, wenn Sie .fn anrufen, dann sind sie nicht austauschbar
Brandon
4
Oh, mir fehlt etwas. 'Window.foo = foo' gibt 'foo' einen globalen Geltungsbereich? Nie neu, das werde ich meiner Liste der zu lernenden Techniken hinzufügen.
EE33
2
@ EE33 Wenn ich mich nicht irre, bedeutet der globale Bereich in Javascript einfach, dass Ihre Variable ein Parameter des Fensterobjekts ist.
Shawn
1
@ Imray - return thisum Verkettung zu ermöglichen , so könnten Sie tunfoo("bar").myPlugin().otherPlugin()
Racing Tadpole
3
@Shawn Ich denke, es würde eine Eigenschaft genannt werden, kein Parameter, oder? Ein Parameter wäre hier die Variable 'a' function func1 (a) { ... }, und eine Eigenschaft wäre hier die Variable 'a' var foo = {}; foo.a = 'a'.
Zack
145

jQuery.fnist eine Kurzform für jQuery.prototype. Aus dem Quellcode :

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

Das heißt, es jQuery.fn.jqueryhandelt sich um einen Alias ​​für jQuery.prototype.jquery, der die aktuelle jQuery-Version zurückgibt. Wieder aus dem Quellcode :

// The current version of jQuery being used
jquery: "@VERSION",
Andy E.
quelle
15
Ich mag diese Antwort. Ich zeige genau, wie man die Definition im Quellcode findet und wie man die Definition auf nützliche Weise interpretiert. Die gute alte Antwortmethode "Bringe einem Mann das Fischen bei". +1.
EE33
aber was ist der Zweck davon? Nur ein paar Tastenanschläge sparen?
Slier
@slier: ja so ziemlich.
Andy E
Ich wette, es gibt einen anderen Zweck. Wenn Sie eine Funktion an $ .fn anhängen, wird die statische Funktion
Slier
145

fnbezieht sich wörtlich auf die Abfrage prototype.

Diese Codezeile befindet sich im Quellcode:

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

Das eigentliche Werkzeug dahinter fnist jedoch die Verfügbarkeit, um Ihre eigenen Funktionen in jQuery einzubinden. Denken Sie daran, dass jquery der übergeordnete Bereich Ihrer Funktion ist und sich daher thisauf das jquery-Objekt bezieht.

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

Hier ist ein einfaches Beispiel dafür. Nehmen wir an, ich möchte zwei Erweiterungen erstellen, eine, die einen blauen Rand setzt und die den Text blau färbt, und ich möchte, dass sie verkettet werden.

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;
};

Jetzt können Sie diese gegen eine Klasse wie diese verwenden:

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

(Ich weiß, dass dies am besten mit CSS möglich ist, z. B. mit dem Anwenden verschiedener Klassennamen, aber bitte denken Sie daran, dass dies nur eine Demo ist, um das Konzept zu zeigen.)

Diese Antwort enthält ein gutes Beispiel für eine vollwertige Erweiterung.

Travis J.
quelle
11
Können Sie den eachCode in Ihrem Beispielcode nicht einfach überspringen ? $.fn.blueBorder = function(){ this.css("border","solid blue 2px"); return this; };würde gut funktionieren, da .css()alerady über die Elemente iteriert.
SoonDead
6
@SoonDead - Sie könnten es sicherlich tun, denn wenn das jQuery-Objekt eine Auflistung enthält, wird die cssFunktion diese bei jedem automatisch intern durchlaufen. Es war nur ein Beispiel für die Darstellung der Unterschiede, bei thisdenen das äußere das Abfrageobjekt ist und das innere auf das Element selbst verweist.
Travis J
1
@SoonDead Guter Kommentar, aber ich mag es wirklich, wie Travis J die Idee / das Prinzip erklärt hat. :)
Sander
5
Dies ist der beste Kommentar - Zu wissen, dass fn nur ein Alias ​​ist, ist bei weitem nicht so nützlich wie zu wissen, warum sich jemand darum kümmern sollte, und diese Antwort hat es wunderbar demonstriert.
Gerard ONeill
1
Nachdem ich die anderen Antworten durchgesehen hatte, stellte ich fest, dass diese das Hauptkonzept leichter verstehen. Vielen Dank. :)
VivekP
0

Im jQuery-Quellcode, den wir haben, jQuery.fn = jQuery.prototype = {...}da jQuery.prototypees sich um ein Objekt handelt, ist der Wert von jQuery.fneinfach ein Verweis auf dasselbe Objekt wiejQuery.prototype bereits verwiesen wird.

Um dies zu bestätigen, können Sie überprüfen, jQuery.fn === jQuery.prototypeob dies ausgewertet wird true(was es tut), dann verweisen sie auf dasselbe Objekt

Yehuda Schwartz
quelle