O que significa o jQuery.fn?


Respostas:


848

No jQuery, a fnpropriedade é apenas um alias para a prototypepropriedade.

O jQueryidentificador (ou $) é apenas uma função do construtor e todas as instâncias criadas com ele herdam do protótipo do construtor.

Uma simples função construtora:

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

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

Uma estrutura simples que se assemelha à arquitetura do 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"

4
Isso é garantido para ser verdade? Posso assumir que uma chamada para jQuery.prototype é exatamente igual a jQuery.fn? Minha preocupação é se jQuery faz alguma mágica quando você chamar .fn então eles não são intercambiáveis
Brandon

4
Ah, estou faltando alguma coisa .. 'window.foo = foo' fornece a 'foo' um escopo global? nunca novo isso, vou adicioná-lo à minha lista de técnicas para aprender.
EE33

2
@ EE33 Se não me engano, o âmbito global em javascript significa simplesmente que a sua variável é um parâmetro do objecto da janela.
Shawn

1
@Imray - return thispara permitir o encadeamento , assim que você poderia fazerfoo("bar").myPlugin().otherPlugin()
Corrida Girino

3
@ Shawn Eu acho que seria chamado de propriedade, não um parâmetro, certo? Um parâmetro seria a variável 'a' aqui function func1 (a) { ... }e uma propriedade seria a variável 'a' aqui var foo = {}; foo.a = 'a'.
Zack

145

jQuery.fné definido como abreviação para jQuery.prototype. Do código fonte :

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

Isso significa que jQuery.fn.jqueryé um alias para jQuery.prototype.jquery, que retorna a versão atual do jQuery. Novamente a partir do código fonte :

// The current version of jQuery being used
jquery: "@VERSION",

15
Eu gosto desta resposta. Mostro exatamente como encontrar a definição dentro do código-fonte e, em seguida, como interpretar a definição de uma maneira útil. O bom e velho "ensinar um homem a pescar" o método de resposta. +1.
EE33

mas qual é o propósito de fazer isso? apenas salvando algumas teclas?
Slier

@ slier: sim, praticamente.
Andy E

Aposto que é outra função purpose..attaching para US $ .fn, fará função estática
Slier

145

fnliteralmente se refere ao jquery prototype.

Esta linha de código está no código fonte:

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

Mas a ferramenta real fné a disponibilidade para conectar sua própria funcionalidade ao jQuery. Lembre-se de que jquery será o escopo pai da sua função, portanto, thisse referirá ao objeto jquery.

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

Então, aqui está um exemplo simples disso. Digamos que eu quero fazer duas extensões, uma que coloque uma borda azul e que colore o texto em azul, e eu as quero encadeadas.

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

Agora você pode usá-los contra uma classe como esta:

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

(Eu sei que isso é melhor feito com css, como a aplicação de nomes de classe diferentes, mas lembre-se de que é apenas uma demonstração para mostrar o conceito)

Esta resposta tem um bom exemplo de uma extensão completa.


11
Você não pode simplesmente pular o eachcódigo de exemplo? $.fn.blueBorder = function(){ this.css("border","solid blue 2px"); return this; };funcionaria bem, pois .css()alerady itera sobre os elementos.
SoonDead

6
@SoonDead - Você certamente poderia, porque se o objeto jQuery contiver uma coleção, a cssfunção iterará automaticamente sobre eles internamente com cada um. Foi apenas um exemplo de mostrar as diferenças de thisonde o externo é o objeto jquery e o interno faz referência ao próprio elemento.
Travis J

1
@SoonDead Bom comentário, mas eu realmente gosto de como Travis J explicou a ideia / princípio. :)
Sander

5
Este é o melhor comentário - saber que fn é apenas um pseudônimo não é tão útil quanto saber por que alguém deveria se importar, e esta resposta demonstrou isso de maneira bonita.
precisa saber é o seguinte

1
Depois de analisar as outras respostas, achei mais fácil entender o conceito principal. Obrigado. :)
VivekP 10/10/19

0

No código-fonte jQuery que temos jQuery.fn = jQuery.prototype = {...}desde então, jQuery.prototypeé um objeto cujo valor jQuery.fnserá simplesmente uma referência ao mesmo objeto que jQuery.prototypejá faz referência.

Para confirmar isso, você pode verificar jQuery.fn === jQuery.prototypese isso avalia true(o que faz), em seguida, eles fazem referência ao mesmo objeto

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.