Invocation

Alternative ways to invoke a function or a method.



Usage in JavaScript:
high


Fundamentals


Earlier we had mentioned that each function in JavaScript comes with two bonus arguments: arguments and this. These are not visible in the formal parameter list but are passed in by the compiler and are available to the entire function scope. The arguments parameter holds all arguments that were provided when the function was called. Here we will focus on the second bonus argument: this.

All object-oriented programming languages have a similar concept to JavaScript's this. It may be called this, me, or self, but they all reference the same thing; the object context that the function executes in. Object context sounds complicated, but an easy way to remember this is that it provides the function an answer to the question where am I, that is, which object instance am I part off?

In JavaScript, the value of this is determined by its Invocation pattern. There are 4 versions: the function invocation pattern, the method invocation pattern, the constructor invocation pattern and the apply invocation pattern. They all differ in how they initialize the value of this. We'll look at each of these.

Function Invocation Pattern
First of all, we need to distinguish functions from methods. A standalone function that is not part of an object is called a function or a global function because it resides on the global object. A function that is defined as part of an object is called a method. The this value in a (global) function is bound to the global object. This is the Function Invocation Pattern. Here is an example:

function show() {
    alert(this === window);    // => true
    alert(this)                // => [object Window]
}

show();
Run

This confirms that this is indeed bound to the global object. Note that the above code only works in the browser (and not on the server) because window is the name given to the global object in browsers.

Method Invocation Pattern
As mentioned, a method is a function member of an object. When a method is invoked, then the this value is bound to the object instance. This is called the Method Invocation Pattern. Consider this code:

var calculator = {
    total: 0,
    add: function (x) { this.total += x; },
    sub: function (x) { this.total -= x; },
    show: function () { alert("total = " + this.total); }
}

calculator.add(10);
calculator.show();       // => total = 10

calculator.sub(6);
calculator.show();       // => total = 4

Run

In all three methods (add, sub, show) the value of this is bound to the surrounding object instance. These methods have full read-write access to the object's properties (in this example just this.total). Outside the object the total property can be accessed by calculator.total and inside the object it is accessible as this.total.

Constructor Invocation Pattern
Invoking a constructor function with the new operator creates a new object. Not surprisingly, the this variable will be bound to the newly created object. This is called the Constructor Invocation Pattern.

There are three steps that take place when executing a constructor function. First a new object is created which is then bound to this. Next, the function body executes and properties and methods are added to the object. And, finally, the constructor function implicitly returns the newly created object (you can overwrite the return value by explicitly returning another object but there is rarely a reason to do so).

Here is an example:

var Calculator = function () {
    this.total = 0;
    this.add  = function (x) { this.total += x; };
    this.sub = function (x) { this.total -= x; },
    this.show = function () { alert("total = " + this.total); }
}

var calculator = new Calculator();

calculator.add(10);
calculator.show();       // => total = 10

calculator.sub(6);
calculator.show();       // => total = 4

Run

Invoking a constructor function without the new operator changes the Invocation pattern from a Constructor Invocation pattern to a Function Invocation pattern. Remember that the Function Invocation pattern binds this to the global object, so forgetting the new can be a serious problem. We have already discussed this issue and a safeguard in the Constructor pattern.

As an alternative you can move the calculator's methods to its prototype, like so:

var Calculator = function () {
    this.total = 0;
}

Calculator.prototype = {
    add: function (x) { this.total += x; },
    sub: function (x) { this.total -= x; },
    show: function () { alert("total = " + this.total); }
}

var calculator = new Calculator();

calculator.add(10);
calculator.show();       // => total = 10

calculator.sub(6);
calculator.show();       // => total = 4

Run

In the prototype definition the this value is also bound to the calculator object instance.

Apply Invocation pattern
The Application Invocation pattern offers the most flexibility. You use the apply function to invoke a function and then set the this value yourself. Two arguments are needed: first the value for this, and secondly an array of arguments used to invoke the function. Here is an example:

function giveName(first, last) {
    this.first = first;
    this.last = last;
};
var person = {};

giveName.apply(person, ["Neil", "Anderson"]);

alert(person.first + " " + person.last);   // => Neil Anderson

Run

The giveName function assigns a first and last name to an object. We have an empty object named person and then apply the giveName function to it. The first argument is the person object (which is bound to this) and a two-element array with the first and last as the second argument. The alert shows that person now has the name Neil Anderson.

In addition to apply, JavaScript comes with a very similar built-in function called call. It does exactly the same, but the difference is that the second argument is not an array, but a series of individual arguments. Here is an example:

function giveName(first, last) {
    this.first = first;
    this.last = last;
};
var person = {};

giveName.call(person, "Neil", "Anderson");

alert(person.first + " " + person.last);   // => Neil Anderson

Run

The Apply Invocation pattern is a powerful pattern. You can use it with any object as long as it supports the interface that the function expects. Essentially, you are able to attach 'temporary methods' to all objects that meet a certain interface requirement. Actually, in the above example giveName works for any object as there are no requirements to the object's interface: it creates (or overwrites) a first and last property and assigns the values provided.

If you are coming from .NET you will recognize the Apply Invocation pattern as .NET's extension methods. Extension methods have a slightly different syntax, but the effects are the same: you get full control over what object this is bound to. The name extension method is very appropriate as you are temporarily extending objects with these methods. Another name you may see in JavaScript for the Apply Invocation pattern is the borrow method pattern which also describes the pattern well. Finally, delegation has also been used as a name for apply/call method invocation.

The common thread in the Invocation methods is the binding of this. The 4 patterns demonstrate that it can be bound to the global object, the current object instance, a newly created object, or anything we choose.

In object-oriented programming the hidden this parameter is an important concept; it is the context (i.e. object) in which the function executes. The value of this is bound just before the function begins execution. This is called late binding, because it takes place at runtime at such a late stage. It makes these functions highly reusable as it allows them to do their work in many different contexts.



  Chaining
Mixin