614

What does the fn here mean?

jQuery.fn.jquery
Yehuda Schwartz
  • 3,378
  • 3
  • 29
  • 38
ajsie
  • 77,632
  • 106
  • 276
  • 381

5 Answers5

885

In jQuery, the fn property is just an alias to the prototype property.

The jQuery identifier (or $) is just a constructor function, and all instances created with it, inherit from the constructor's prototype.

A simple constructor function:

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

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

A simple structure that resembles the architecture of 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"
Christian C. Salvadó
  • 807,428
  • 183
  • 922
  • 838
  • 4
    Is this guaranteed to be true? Can I assume a call to jQuery.prototype is exactly the same as jQuery.fn? My worry is if jQuery does some magic when you call .fn then they aren't interchangeable – Brandon Feb 24 '12 at 14:08
  • how can you extend 'foo' in your example if 'foo' was declared only inside of the anonymous function? Am I missing something? – E.E.33 Mar 05 '12 at 19:37
  • 4
    Oh, I am missing something.. 'window.foo = foo' gives 'foo' a global scope? never new that, I'll add that to my list of techniques to learn. – E.E.33 Mar 05 '12 at 19:45
  • 2
    @E.E.33 If I'm not mistaken, the global scope in javascript simply means that your variable is a parameter of the window object. – Shawn Sep 20 '12 at 17:53
  • @Shawn you are correct, that is why 'foo' had to explicitly be assigned to 'window.foo'. otherwise, the window object wouldn't have the reference. – E.E.33 Oct 15 '12 at 03:24
  • Can you explain why you need `return this;`? – CodyBugstein Jul 16 '14 at 15:34
  • 1
    @Imray - `return this` to allow [chaining](http://learn.jquery.com/plugins/basic-plugin-creation/#chaining), so you could do `foo("bar").myPlugin().otherPlugin()` – Racing Tadpole Feb 12 '15 at 01:44
  • 3
    @Shawn I think it would be called a property, not a parameter, right? A parameter would be the 'a' variable here `function func1 (a) { ... }`, and a property would be the 'a' variable here `var foo = {}; foo.a = 'a'`. – Zack Feb 27 '15 at 16:00
  • 1
    Because of the prototype tree search, the new method will work on an existing object too: `var Foo = function(){};var bar = new Foo();Foo.prototype.x=function(){alert("x");};bar.x();` alerts "x". – Dávid Horváth Dec 20 '15 at 15:46
164

fn literally refers to the jquery prototype.

This line of code is in the source code:

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

But the real tool behind fn is its availability to hook your own functionality into jQuery. Remember that jquery will be the parent scope to your function, so this will refer to the jquery object.

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

So here is a simple example of that. Lets say I want to make two extensions, one which puts a blue border, and which colors the text blue, and I want them chained.

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

Now you can use those against a class like this:

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

(I know this is best done with css such as applying different class names, but please keep in mind this is just a demo to show the concept)

This answer has a good example of a full fledged extension.

Travis J
  • 81,153
  • 41
  • 202
  • 273
  • 11
    Can't you just skip the `each` in your example code? `$.fn.blueBorder = function(){ this.css("border","solid blue 2px"); return this; };` would work fine, as `.css()` alerady iterates over the elements. – vinczemarton May 09 '13 at 12:31
  • 6
    @SoonDead - You certainly could because if the jQuery object holds a collection then the `css` function will automatically iterate over them internally with each. It was just an example of showing the differences in `this` where the outer one is the jquery object and the inner one references the element itself. – Travis J May 09 '13 at 18:43
  • 1
    @SoonDead Good comment, but I really like how Travis J explained the idea/principle. :) – Sander May 30 '14 at 07:53
  • 5
    This is the best comment -- Knowing that fn is just an alias is not nearly as useful as knowing why anyone should care, and this answer demonstrated it beautifully. – Gerard ONeill Aug 06 '15 at 19:49
  • Well, why not just use `$.prototype.blueBorder` ? Is this just so that you don't have to type more letters? – doubleOrt Dec 08 '17 at 05:31
  • 1
    After going through the other answers, I found this one to be easier to understand the main concept. Thank you. :) – VivekP Oct 10 '19 at 06:08
152

jQuery.fn is defined shorthand for jQuery.prototype. From the source code:

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

That means jQuery.fn.jquery is an alias for jQuery.prototype.jquery, which returns the current jQuery version. Again from the source code:

// The current version of jQuery being used
jquery: "@VERSION",
Andy E
  • 338,112
  • 86
  • 474
  • 445
  • 16
    I like this answer. I shows exactly how to find the definition inside the source code, and then how to interpret the definition in a useful manner. The good ol' "teach a man to fish" method of answering. +1. – E.E.33 Mar 05 '12 at 19:39
  • but what is the purpose of doing that? just saving couple of keystroke? – slier Feb 20 '15 at 10:43
  • @slier: yes, pretty much. – Andy E Feb 23 '15 at 09:00
  • i bet there is other purpose..attaching function to $.fn, will make static function – slier Feb 23 '15 at 18:29
19

The $.fn is an alias for jQuery.prototype which allows you to extend jQuery with your own functions.

For Example:

 $.fn.something = function{}

will allow you to use

$("#element").something()

The $.fn is also synonymous with jQuery.fn.

Jerry King
  • 454
  • 4
  • 6
3

In the jQuery source code we have jQuery.fn = jQuery.prototype = {...} since jQuery.prototype is an object the value of jQuery.fn will simply be a reference to the same object that jQuery.prototype already references.

To confirm this you can check jQuery.fn === jQuery.prototype if that evaluates true (which it does) then they reference the same object

Yehuda Schwartz
  • 3,378
  • 3
  • 29
  • 38