views:

72

answers:

2
(function($)
{
$.vari = "$.vari";
$.fn.vari = "$.fn.vari";

// $.fn is the object we add our custom functions to
$.fn.DoSomethingLocal = function()
{
    return this.each(function()
    {
        alert(this.vari);    // would output `undefined`
        alert($(this).vari); // would output `$.fn.vari`
    });
};
})(jQuery);

// $ is the main jQuery object, we can attach a global function to it
$.DoSomethingGlobal = function()
{
    alert("Do Something Globally, where `this.vari` = " + this.vari);
};

$(document).ready(function()
{
    $("div").DoSomethingLocal();
    $.DoSomethingGlobal();
});

I am confused why in the $.fn.DoSomethingLocal function, $(this).vari is the string "$.fn.vari" and not "$.vari". I thought that the this reference in the each call gives a dom object, so calling $(this) returns a standard jquery object with prototype $, not $.fn.

How does this happen?

+3  A: 

The jQuery.fn namespace is inherited by jQuery objects. So if you write $.fn.somewhat you now can access this by $().somewhat. That is why any jQuery plugin has to extend the jQuery.fn object/namespace.

The pattern jQuery.somewhat would just extend the plain object with somewhat. That is as good as window.somewhat or anyobject.somewhat.

$.fn has a prototypal inheritance, that is all the magic.

return this.each(function()
{
    alert(this.vari);    // would output `undefined`
    alert($(this).vari); // would output `$.fn.vari`
});

In this context, this always refers to the object of invocation, that is, a jQuery object. Since all jQuery objects inherit from jQuery.fn you are getting $.fn.vari here.

note

Within the scope of $.fn, this references to a jQuery object !

Within the scope of .each(), this references to a DOM node !

Why?

Javascript's .apply() function allows you to specify the context in which you want to execute a function. That principle is used by "Resig & the boys" to "derefer" this.

jAndy
+1 As I understand the code, `jQuery.fn` is a reference to `jQuery.prototype`. http://github.com/jquery/jquery/blob/master/src/core.js#L61
patrick dw
A: 

when iterating through a jquery object with .each(), this referes to the element NOT wrapped in a jquery object. The method jQuery.vari() is on the jquery object, not the elements, so you have to wrap the element in a jquery object before you can call the $.vari() method.

Tentonaxe