JavaScript performance library

In JavaScript, this keyword always depends on how given function is invoked. There are four patterns to invocate a JavaScript function. Understanding those patterns is important knowledge to understand how JavaScript this keyword works.

Learn JavaScript this keyword by reading this article.

JavaScript this keyword

In a JavaScript function, this keyword refer to the object that the function is a method of. Every function invocation pattern differ in how JavaScript this variable is initialized.

 Method Invocation

A function is called a method when it is stored as a property of an object. When a method is invoked, this keyword is bound to the object where the function is defined.

A function is defined as a method when it’s invoked through an object (contains a dot or [] expression, ie. someObject.myFunc() or someObject["myFunc"]()).

var someObject = {
    message: "Hello!",
    greetMe: function() {
        // "this" bounds to someObject and allows to access it's properties
        alert(this.message); 
    }
}

someObject.greetMe(); // = Hello!

Function Invocation

Invocation as a function takes place when a function is not a property of an object.

When a function is invoked this way, this keyword is bound to the global object. In web browsers this global object will be window.

var func = function() {
    alert(this === window);
};

func(); // = true

Invocation as a function can take place also when a function is inside of some object:

window.message = "I am the window object!";

var someObject = {
    message: "I am the someObject!",
    invokeMethod: function() {
        alert(this.message); 
    },
    invokeFunction: function() {
        var func = function() {
            alert(this.message);
        }
        
        func();
    }
}

someObject.invokeMethod(); // = "I am the someObject!"
someObject.invokeFunction(); // = "I am the window object!"

The way of this behavior during invocation as a function is a terrible mistake of JavaScript design. Thankfully, there exist a very handy workaround that allows to access properties of the object in which the function is defined:

window.message = "I am the window object!";

var someObject = {
    message: "I am the someObject!",
    invokeMethod: function() {
        alert(this.message); 
    },
    invokeFunction: function() {
        var that = this;
        
        var func = function() {
            alert(that.message); // notice "that"
        }
        
        func();
    }
}

someObject.invokeMethod(); // = "I am the someObject!"
someObject.invokeFunction(); // = "I am the someObject!

 Constructor Invocation

When a function is invoked by using the new prefix, a new object is created (and returned) using prototype of this function (read more about prototypes in this post).

During Constructor Invocation of a function this keyword refers to the newly created object.

window.message = "I am window.message"

// Constructor invocation example
var Messenger = function(message) {
    this.message = message;
}

var myObject = new Messenger("I am myObject.message");
alert(window.message);   // = I am window.message
alert(myObject.message); // = I am myObject.message
// In Constructor Invocation "this" refers to 
// the object being created, thus this.message in Messenger
// set "message" property in "myObject", not "window"

// Function invocation example
Messenger("I am set by Invocation as Function");
alert(window.message); // = I am set by Invocation as Function
// In Function Invocation "this" refers to
// the global object, thus this.message in Messenger
// set "message" property in the global object "window"

Invocation of a constructor function in any other way than with usage of new prefix may lead to terrible consequences. An example can be unintentional overriding of the global object, as shown in the example above.

Due to this problem there is a very important convention that marks which functions should be always invoked as a constructor. Every function that should be invoked as a constructor should begin it’s name with a capitalized letter.

Notice that the name of constructor function Messenger starts with a capitalized letter specially to mark that it should be always invoked as a constructor. Please keep in mind this convention to prevent problems in your and others code.

.apply() Invocation

The apply() method is present in every JavaScript function. It allows to invoke a function with this bounded to an object of your choice.

apply() method accepts two arguments. The first is a replacement for this object. The second is an array of arguments that is passed to that function.

The syntax of apply() is following:

func.apply(thisObject, arrayOfParameters)

Usage example:

var someObject = {
    message: "I am someObject",
    getMessage: function(p1, p2) {
        alert(this.message + "; Params: "+p1+","+p2);
    }
}

var otherObject = {
    message: "I am otherObject"
}

someObject.getMessage("x", "y"); // = I am someObject; Params: x,y
someObject.getMessage.apply(otherObject, ["x", "y"]); // = I am otherObject; Params: x,y