This blog post is for developers who already know how to write software and want to learn about Javascript and “this”. I am not teaching you how to write software because I assume you might code in a different language.

If we use car.engine and car.seatCount, our code becomes ambiguous. Consider that there could be another global variable (that we might or might not be aware of) with the name “car.” JavaScript coding techniques and design patterns have become increasingly sophisticated over the years, there’s been a corresponding increase in the proliferation of self-referencing scopes within callbacks and closures, which are a fairly common source of “this/that confusion”.

If you understand the this paradigm in Javascript, you will understand the “this” keyword with clarity: this is not assigned a value until an object invokes the function where the this keyword is defined. However, there are moments through out your development where this does not have the value of the invoking object. Lets look at an example where Game is an object that has a restart functions. The restart logic requires a timeout of o milliseconds when ever it gets called.

Game.prototype.restart = function () {
    this.clearLocalStorage();
    this.timer = setTimeout(function() {
        this.clearBoard();    // to what is "this" a reference to?
    }, 0);
};

The reason you get the above error is because, when you invoke setTimeout(), you are actually invoking window.setTimeout(). A traditional solution is to simply save your reference to this in a variable, such as in self that can then be inherited by the closure.

Game.prototype.restart = function () {
    this.clearLocalStorage();
    var self = this;   // reference to 'this', while it's still this!
    this.timer = setTimeout(function(){
        self.clearBoard();
    }, 0);
};

First, know that all functions in Javascript have properties, just as objects have properties. And when a function executes, it gets the this property—a variable with the value of the object that invokes the function where this is used. Sounds confusing, right? Worry not. Alternatively, in newer browsers, you can use the bind() method to pass in the proper reference. But that is tedious and prone to errors when you consider how much code you’ll write along your development career.

We mentioned .bind which

Context with call and apply in Javascript

The Apply and Call methods are two of the most often used Function methods in JavaScript, and for good reason: they allow us to borrow functions and set the this value in function invocation. In addition, the apply function in particular allows us to execute a function with an array of parameters, such that each parameter is passed to the function individually when the function executes, lets show an example:

var personObject = {
    "firstName": "Michel",
    "lastName": "Herszak",
}

var assembleName = function () {
    console.log(this.firstName + " " + this.lastName);
}

// Do it the wrong way where this is refers to the global object where firstName and lastName is not defined
assembleName(); // output: undefined undefined

// now use call and you call the function sayName and bind the person object to it
assembleName().call(personObject); // output: Michel Herszak

What call does it invokes the function and binds the object and the this value to its context. Lets make our assemble function a bit more flexible and pass arguments.

var assembleName = function (arg1,arg2) {
    console.log(this[arg1]);
    console.log(this[arg2]);
}

assembleName().call(personObject,'lastName','firstName'); // output: Herszak Michel

In this example we expect assemble function to obtain arguments and pass those into the call function. This functions excepts your arguments as you would pass arguments to any other function, except that the first parameter is the actual reference to this as in the current object context.

Apply, Call, and Bind methods are all used to set the this value when invoking a method, and they do it in slightly different ways to allow use direct control and versatility in our JavaScript code. One difference, though, is that apply expects your parameters as an array of arguments, like so.

assembleName().apply(personObject,['lastName','firstName']); // output: Herszak Michel

So apply translates the actual values from the object you bind the this pointer, too. Another snippet is they way you could invoke apply:

var newFunc = function(){
    assembleName().apply(personObject,arguments);
};

newFunc('firstName','lastName');

What newFunc does it translates all arguments into an array and passes that as a second parameter to the apply function.

So remember:

  • the new operator creates a context
  • this is assigned to the object instance that invokes a random method at a particular point in time
  • You can use bind and bind your context
  • You can simply use variables like self to bind this to a particular scope
  • Think about ways to incorporate apply and call into your code base

Email — michel.herszak@gmail.com

Twitter — @MHerszak (twitter.com/MHerszak)

Want to know about the way in which I work? Great, you can get started with an overview of just how I approach a project right here.

Further information can be found here.