Co oznacza jQuery.fn?

Odpowiedzi:

848

W jQuery fnwłaściwość jest tylko aliasem prototypewłaściwości.

jQueryIdentyfikator (lub $) jest tylko funkcja konstruktora , a wszystkie instancje stworzone z nim dziedziczyć z prototypu konstruktora.

Prosta funkcja konstruktora:

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

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

Prosta struktura, która przypomina architekturę 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
źródło
4
Czy to prawda, że ​​to prawda? Czy mogę założyć, że wywołanie do jQuery.prototype jest dokładnie takie samo jak jQuery.fn? Martwię się, że jeśli jQuery wywołuje magię, gdy dzwonisz .fn, to nie są one wymienne
Brandon
4
Och, brakuje mi czegoś ... 'window.foo = foo' daje 'foo' zasięg globalny? nigdy tego nowego, dodam to do mojej listy technik do nauki.
EE33
2
@ EE33 Jeśli się nie mylę, globalny zasięg w javascript oznacza po prostu, że twoja zmienna jest parametrem obiektu okna.
Shawn,
1
@Imray - return thisaby umożliwić tworzenie łańcuchów , abyś mógł to zrobićfoo("bar").myPlugin().otherPlugin()
Racing Tadpole
3
@Shawn Myślę, że nazywa się to właściwością, a nie parametrem, prawda? Parametr byłby tutaj zmienną „a” function func1 (a) { ... }, a właściwością byłaby tutaj zmienna „a” var foo = {}; foo.a = 'a'.
Zack
145

jQuery.fnjest zdefiniowany jako skrót jQuery.prototype. Z kodu źródłowego :

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

To oznacza jQuery.fn.jqueryalias dla jQuery.prototype.jquery, który zwraca bieżącą wersję jQuery. Znów z kodu źródłowego :

// The current version of jQuery being used
jquery: "@VERSION",
Andy E.
źródło
15
Podoba mi się ta odpowiedź. Pokazuję dokładnie, jak znaleźć definicję w kodzie źródłowym, a następnie jak interpretować definicję w użyteczny sposób. Dobry stary sposób „uczyć człowieka łowienia”. +1.
EE33
ale jaki jest tego cel? oszczędzasz tylko kilka klawiszy?
płasko
@slier: tak, właściwie.
Andy E
Założę się, że jest inny cel .. funkcja dołączenia do $ .fn, sprawi, że funkcja statyczna
płynna
144

fndosłownie odnosi się do jquery prototype.

Ten wiersz kodu znajduje się w kodzie źródłowym:

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

Ale prawdziwym narzędziem stojącym za tym fnjest jego dostępność do podłączenia własnej funkcjonalności do jQuery. Pamiętaj, że jquery będzie nadrzędnym zakresem dla twojej funkcji, więc thisbędzie odnosić się do obiektu jquery.

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

Oto prosty tego przykład. Powiedzmy, że chcę zrobić dwa rozszerzenia, z których jedno ustawia niebieską ramkę i które koloruje tekst na niebiesko, i chcę, aby były powiązane.

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

Teraz możesz użyć tych przeciwko takiej klasie:

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

(Wiem, że najlepiej to zrobić przy użyciu css, takich jak stosowanie różnych nazw klas, ale pamiętaj, że to tylko demonstracja pokazująca koncepcję)

Ta odpowiedź ma dobry przykład pełnego rozszerzenia.

Travis J
źródło
11
Nie możesz po prostu pominąć eachkodu przykładowego? $.fn.blueBorder = function(){ this.css("border","solid blue 2px"); return this; };działałoby dobrze, ponieważ .css()alerady iteruje po elementach.
SoonDead
6
@SoonDead - Z pewnością możesz, ponieważ jeśli obiekt jQuery przechowuje kolekcję, cssfunkcja automatycznie iteruje nad nimi wewnętrznie z każdym z nich. Był to tylko przykład pokazania różnic, w thisktórych zewnętrzny jest obiektem jquery, a wewnętrzny odwołuje się do samego elementu.
Travis J
1
@SoonDead Dobry komentarz, ale naprawdę podoba mi się to, jak Travis J wyjaśnił pomysł / zasadę. :)
Sander
5
To najlepszy komentarz - Świadomość, że fn jest tylko pseudonimem, nie jest tak przydatna, jak wiedza, dlaczego ktoś powinien się tym przejmować, a ta odpowiedź pięknie to pokazała.
Gerard ONeill,
1
Po przejrzeniu innych odpowiedzi okazało się, że jest to łatwiejsze do zrozumienia głównej koncepcji. Dziękuję Ci. :)
VivekP,
0

W kodzie źródłowym jQuery, który mamy, jQuery.fn = jQuery.prototype = {...}ponieważ jQuery.prototypejest to obiekt, którego wartość jQuery.fnbędzie po prostu odwołaniem do tego samego obiektu, który jQuery.prototypejuż się odwołuje.

Aby to potwierdzić, możesz sprawdzić, jQuery.fn === jQuery.prototypeczy to ocenia true(co robi), a następnie odwołują się do tego samego obiektu

Yehuda Schwartz
źródło