¿Qué significa jQuery.fn?


Respuestas:


848

En jQuery, la fnpropiedad es solo un alias de la prototypepropiedad.

El jQueryidentificador (o $) es solo una función de constructor , y todas las instancias creadas con él, heredan del prototipo del constructor.

Una función constructora simple:

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

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

Una estructura simple que se asemeja a la arquitectura 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"

44
¿Se garantiza que esto sea cierto? ¿Puedo suponer que una llamada a jQuery.prototype es exactamente la misma que jQuery.fn? Mi preocupación es si jQuery hace algo de magia cuando llamas .fn, entonces no son intercambiables
Brandon

44
Oh, me falta algo ... 'window.foo = foo' le da a 'foo' un alcance global? nunca nuevo eso, lo agregaré a mi lista de técnicas para aprender.
EE33

2
@ EE33 Si no me equivoco, el alcance global en JavaScript simplemente significa que su variable es un parámetro del objeto de ventana.
Shawn

1
@ Imray - return thispara permitir el encadenamiento , para que puedas hacerlofoo("bar").myPlugin().otherPlugin()
Racing Tadpole

3
@ Shawn Creo que se llamaría una propiedad, no un parámetro, ¿verdad? Un parámetro sería la variable 'a' aquí function func1 (a) { ... }, y una propiedad sería la variable 'a' aquí var foo = {}; foo.a = 'a'.
Zack

145

jQuery.fnse define como taquigrafía para jQuery.prototype. Del código fuente :

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

Eso significa que jQuery.fn.jqueryes un alias para jQuery.prototype.jquery, que devuelve la versión actual de jQuery. De nuevo desde el código fuente :

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

15
Me gusta esta respuesta Muestro exactamente cómo encontrar la definición dentro del código fuente, y luego cómo interpretar la definición de una manera útil. El método antiguo de "enseñar a un hombre a pescar" para responder. +1.
EE33

¿Pero cuál es el propósito de hacer eso? solo ahorrando un par de pulsaciones de teclas?
Slier

@slier: sí, más o menos.
Andy E

apuesto a que hay otra función purpose..attaching a $ .fn, hará que la función estática
Slier

145

fnliteralmente se refiere al jquery prototype.

Esta línea de código está en el código fuente:

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

Pero la verdadera herramienta detrás fnes su disponibilidad para conectar su propia funcionalidad a jQuery. Recuerde que jquery será el ámbito principal de su función, por lo que thisse referirá al objeto jquery.

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

Así que aquí hay un ejemplo simple de eso. Digamos que quiero hacer dos extensiones, una que pone un borde azul y que colorea el texto de azul, y quiero encadenarlas.

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

Ahora puedes usarlos contra una clase como esta:

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

(Sé que esto se hace mejor con CSS, como aplicar diferentes nombres de clase, pero tenga en cuenta que esto es solo una demostración para mostrar el concepto)

Esta respuesta tiene un buen ejemplo de una extensión completa.


11
¿No puedes saltarte el eachcódigo de ejemplo? $.fn.blueBorder = function(){ this.css("border","solid blue 2px"); return this; };funcionaría bien, ya que .css()alerady itera sobre los elementos.
SoonDead

66
@SoonDead: ciertamente podría hacerlo porque si el objeto jQuery contiene una colección, la cssfunción iterará automáticamente sobre ellos internamente con cada uno. Fue solo un ejemplo de mostrar las diferencias en thisdonde el externo es el objeto jquery y el interno hace referencia al elemento mismo.
Travis J

1
@SoonDead Buen comentario, pero realmente me gusta cómo Travis J explicó la idea / principio. :)
Sander

55
Este es el mejor comentario: saber que fn es solo un alias no es tan útil como saber por qué alguien debería preocuparse, y esta respuesta lo demostró maravillosamente.
Gerard ONeill

1
Después de pasar por las otras respuestas, encontré que esta es más fácil de entender el concepto principal. Gracias. :)
VivekP

0

En el código fuente de jQuery que tenemos, jQuery.fn = jQuery.prototype = {...}ya que jQuery.prototypees un objeto, el valor de jQuery.fnserá simplemente una referencia al mismo objeto que jQuery.prototypeya hace referencia.

Para confirmar esto, puede verificar jQuery.fn === jQuery.prototypesi eso evalúa true(lo que hace) y luego hacen referencia al mismo objeto

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.