The keyword ‘this’ refers to the context in which a given function is running.

Default context

If a function belongs to an object, it is generally called using the dot notation:

var obj = {
  func: function() {
    alert(this === obj); // alerts 'true'
  }
};

obj.func(); // run 'func' in the context of 'obj'

Therefore, by calling obj.func(), we are saying: “Run ‘func’ in the context of ‘obj’, such that the ‘this’ keyword in ‘func’ refers to ‘obj'”

This kind of behavior allows us to do things like this:

var obj = {
  name: 'Joe',
  func: function() {
    alert(this.name); // 'this' is referring to obj, so obj.name gives us 'Joe'
  }
};
obj.func(); // func runs in the context of obj

So far so good, right?

Context coercion

In javascript, we have the power to tell any function to run in the context of absolutely any object we want…not just the one it belongs to, using the magic ‘apply’ and ‘call’ functions:

var obj = {
  name: 'Joe',
  func: function() {
    alert(this.name);
  }
};

var obj2 = {
  name: 'Mike'
};

var obj3 = {
  name: 'Bill'
};

obj.func.apply(obj2); // run 'func' in the context of 'obj2', alerts "Mike"
obj.func.call(obj3); // run 'func' in the context of 'obj3', alerts "Bill"
Both the ‘call’ and ‘apply’ functions give us the ability to specify context. The two are a bit different in that if you wanted to pass arguments to the called function, using ‘apply’ you would pass the arguments as an array while with ‘call’ you would pass individual arguments:
var obj = {
  name: 'Joe',
  func: function(age, weight) {
    alert(this.name+" with age of "+age+" and height of "+weight);
  }
};

var obj2 = {
  name: 'Mike'
};

var obj3 = {
  name: 'Bill'
};

obj.func.apply(obj2, [23, 155]); // run 'func' in the context of 'obj2', alerts "Mike"
obj.func.call(obj3, 43, 176); // run 'func' in the context of 'obj3', alerts "Bill"

So, to review:

  1. Functions that belong to objects can be called using dot notation and run in the context of those objects
  2. Any function can be coerced to run in the context of any other object using the ‘call’ and ‘apply’ methods
  3. Just a reminder, the context of a function is whatever the ‘this’ keyword refers to

Anonymous functions

An anonymous function is one that does not belong to any object. In other words, you can’t call it using dot notation (e.g. someObj.yourFunc() ). Anonymous functions, unless coerced via the ‘call’ or ‘apply’ methods, run in the context of the global scope (usually the ‘window’ object).

var obj = {
  func: function() {
    var anonFunc = function() {
      alert(this === obj); // alerts 'false'
      alert(this === window); // alerts 'true', running in the context of the global object
    };
    anonFunc(); // run anonFunc in...well...no context specified...
  }
};

obj.func(); // run 'func' in the context of 'obj'

So how can we refer to ‘obj’ from the anonFunc? One way is to change the code like so:

var obj = {
  func: function() {
    var anonFunc = function() {
      alert(this === obj); // alerts 'false'
      alert(this === window); // alerts 'true', running in the context of the global object
    };
    anonFunc.call(this); // run anonFunc in the context of 'this', where 'this' is 'obj'
  }
};

obj.func(); // run 'func' in the context of 'obj'

However, a much more common way of fixing this issue is by assigning a variable ‘self’ to the target ‘this’, then just using the ‘self’ variable everywhere.

var obj = {
  func: function() {
    var self = this;
    var anonFunc = function() {
      alert(self === obj); // alerts 'true', since 'self' is set to the 'this' that is the 'obj'
      alert(self === window); // alerts 'false'
    };
    anonFunc(); // run anonFunc in the context of 'this', where 'this' is 'obj'
  }
};

obj.func(); // run 'func' in the context of 'obj'

Here is a more practical example:

var obj = {
  name: "John Doe",
  id: "82384349",
  func: function() {
    var self = this;
    $.get('ajax/getAge', {id: self.id}).done(function(data) {
      alert(self.name+" is "+data+" years old" );
    });
  }
};

obj.func(); // run 'func' in the context of 'obj'

Notice how I declared ‘self’ at the top of the ‘func’ function and then used it everywhere. This has the advantage of making our code less error-prone. Also, if you run your javascript through a minimizer, the ‘self’ variable will be compressed and you will end up with a slightly smaller file then you would if you used ‘this’ everywhere (which does not compress, since it is a keyword in javascript).

Happy Hacking!