Apply, Call and Bind on JavaScript functions

I’m a bit short on time this week so I’ll keep it short. Last week I talked about Prototype in JavaScript, a fundamental JavaScript feature that too few programmers know about. Today I’d like to talk about a few more features that people either don’t know about or are confused about, apply(), call() and bind().

As usual I have the examples on GitHub in the apply-call-bind repository.

Also, in case you missed it, I have a free Udemy course on ReactJS and Flux for you. Only 50, so you best be quick to get it!

Function invocation

So let’s talk a bit about functions and how they can be invoked. Let’s look at a simple function with a simple invocation.

var sum = function (a, b) {
    return a + b;
};
var x = sum(1, 2);
console.log(x);

It doesn’t get simpler than this and x will have the expected value of 3. Let’s make that slightly less simple. We want to be able to add an undefined number of numbers! So how would we handle that? How about this?

var sum = function (numbers) {
    var result = 0;
    numbers.forEach(function(n) {
        result += n;
    });
    return result;
};
var x = sum([1, 2, 3, 4]);
console.log(x);

That looks good, right? Unfortunately, invoking the function is now more difficult as we always need an array. What if I told you there is another way?

Remember that this is JavaScript and JavaScript is, well, weird. We can call a function with any number of input parameters we want. Too few and our function might fail, too much and the extra parameters will be ignored.
There is sense in all this though. Within each function you can inspect the input parameters through an array-like object, arguments.

Let’s rewrite the first version of sum, but using the arguments list this time.

var sum = function () {
    return arguments[0] + arguments[1];
};
var x = sum(1, 2);
console.log(x);

But if we can do that we can use ANY number of parameters! Arguments is array-like, which mean we can loop through the values (it doesn’t have a forEach method though).

var sum = function () {
    var result = 0;
    var i = 0;
    for (i; i < arguments.length; i++) {
        result += arguments[i];
    }
    return result;
};
var x = sum(1, 2, 3, 4);
console.log(x);

That’s pretty nice! We can now use the same simple syntax for any number, or a variable number, of input parameters. So now I’m going to be a real pain in the ass… We got this nice function that takes any number of parameters in the plain and simple syntax we’re used to, but… I want to pass in an array!

Apply

If I were your manager you’d be annoyed at best. I asked for plain and simple syntax, you deliver, and now I want an array after all!? Worry not! Your function is awesome and it can stay. What we’re going to use is a function on the function prototype (meaning all function objects have this function defined), apply.

So that sounded weird… Functions have functions? Yes they do! Remember that a function in JavaScript is just an object. To give you an idea, this is how it looks.

myFunc(); // Invocation of a function.
myFunc.someFunc(); // Invocation of a function on a function.

So let’s look at this function, apply, which allows you to pass input parameters to any function as an array. Apply has two input parameters, the object on which you want to invoke the function (or the object this points to in the function) and the array with input parameters to the function.

So let’s invoke our function, sum, using apply. Notice that the first parameter can be null as we’re not invoking sum on an object.

var x = sum.apply(null, [1, 2, 3, 4]);
console.log(x);

So that’s awesome, right? Let’s look at an example that doesn’t use the arguments variable.

var steve = {
    firstName: 'Steve',
    lastName: 'Ballmer',
    doThatThing: function (what) {
        console.log(this.firstName + ' ' + this.lastName
        + ': ' + what + '! ' + what + '! ' + what + '!');
    }
};
steve.doThatThing.apply(null, ['Developers']);
steve.doThatThing.apply(steve, ['Developers']);

So in this example the function doThatThing is just a regular function with a regular named input parameter and we can still invoke it using apply. In this case we also need to pass in the first parameter to set this. If we don’t specify the first parameter firstName and lastName in the function will be undefined.

We can also put in another variable as first input parameter.

var sander = {
    firstName: 'Sander',
    lastName: 'Rossel'
};
steve.doThatThing.apply(sander, ['Blogs']);

That’s a bit weird, isn’t it? Even though Sander does not have the doThatThing function we can invoke it as if Sander did. This can be very useful behavior as we’ll see in the next section!

Call

Another function, which looks like apply, is call. Call allows you to simply invoke a function, but makes you specify the object which serves as this within the function, much like apply. The only difference between apply and call is the manner in which input parameters are supplied. Apply needs an array with values, call needs the values separated by a comma (like regular function invocations).

steve.doThatThing.call(null, 'Developers');
steve.doThatThing.call(steve, 'Developers');
steve.doThatThing.call(sander, 'Blogs');

So why would you want to do this? It seems it only obfuscates the code… Consider the following scenario, you have some function that takes a callback as input and invokes it.

var someFunc = function (callback) {
    console.log('this is ' + this);
    callback('This');
};
someFunc(steve.doThatThing);

What will it print? Undefined undefined… Sure, when doThatThing is invoked as callback() this will be the global Window object. We have three options now… I’ll discuss two now and I’ll give the third in a minute.
So first we could make it so that this is not used in the callback. For this we’d need to create a closure, or a new function that invokes doThatThing on steve as if it were a normal function.

someFunc(function (what) {
    steve.doThatThing(what);
});

It works, but its a lot of bloated code, so we don’t really want that. So there’s a second option, we allow the this object to be passed to the someFunc as an input parameter. And then we can invoke the function on that object using call (or apply)!

var someFuncThis = function (callback, thisArg) {
    callback.call(thisArg, 'This');
};
someFuncThis(steve.doThatThing, steve);

A lot of JavaScript libraries and frameworks, like jQuery and Knockout.js, use this pattern, passing in this as an optional input parameter.

Bind

If you’ve been paying attention you’ll remember I just said there was a third method to solve our little problem with this in the callback function. Next to apply and call functions also have a bind function. Bind is a function that takes an object as input parameter and returns another function. The function that is returned invokes the original function with the input object as this context. Let’s just look at an example.

someFunc(steve.doThatThing.bind(steve));
someFunc(steve.doThatThing.bind(sander));

And it even works if your original this isn’t the function itself.

var f = steve.doThatThing;
f = f.bind(steve);
someFunc(f);

You’ll need this when passing JavaScript native functions as callbacks to third party libraries.

someFunc(console.log);
someFunc(console.log.bind(console));

The first call fails with an “Illegal invocation” because this inside the log function has to be console, but it isn’t if it’s invoked as callback. The second line works as we’ve bound this to console.

So here are three functions that all invoke a function slightly differently than what you’re used to. All three are indispensable when you’re doing serious JavaScript development though.

If you’d like to know more about functions and how they work in JavaScript I can recommend JavaScript Succinctly.
We’ve also seen a lot of trouble with the this keyword. If you’re wondering why, you should check out this six day course by Derick Bailey: The Rules For Mastering JavaScript’s “this”. I can highly recommend it!

This blog is a bit shorter than usual, but, as they say, it’s quality over quantity. Hope to see you back again next week!

Happy coding!

Prototype in JavaScript

Hey everyone. It’s been a few weeks since I last blogged. I’ve been on a vacation in Poland which was awesome! If you ever want to visit Poland I recommend visiting Gdańsk, a beautiful city, and Malbork Castle, the largest castle in the world!
Anyway, this blog isn’t about travel, it’s about programming, and prototype in JavaScript in particular!

So last time I finished my series on the MEAN stack, MongoDB, Express, AngularJS and Node.js. That meant a lot of JavaScript. Not just front-end, but also back-end. Next to my blog I’ve been writing a lot of JavaScript in my daily life too. And while writing all that JavaScript there was one thing I just didn’t quite understand, prototype. I’m not talking about the library with the same name, which kind of lost the battle for most popular all round JavaScript library to jQuery, I’m talking about prototypal object inheritance. I started asking around. I know some full-stack developers with years of experience in front- and back-end, but guess what? They didn’t fully understand it either! And then I went to look on the interwebs, but guess what? There just aren’t that many good prototype tutorials around. And that’s what this post is all about.

You can find the full code with examples on my GitHub in the repository for this post.

Prototype, you don’t really need it…

So when asking my friends why, after all these years, they still didn’t know prototype their answer was something along the lines of “I never needed it.” Sure, that was the reason I never looked into it before too. Truth is that you can write JavaScript apps and libraries without ever needing it. But if you want to write fast JavaScript code you better start using it!

So first of all, what is prototype and why is using it better than not using it? In JavaScript each function has a prototype property. Prototype has all the, I guess you could call it default, methods and properties that an object, created through that function using the ‘new’ keyword, should have. As we know any object in JavaScript can have any method or property, we can just define them at runtime as we go. And that’s probably the big difference between using it and not using it. With prototype you define methods design time, or up front.

Let’s look at an example. Let’s say I have a Person object, the constructor and usage could look as follows.

var Person = function (firstName, lastName) {
    var self = this;
    self.firstName = firstName;
    self.lastName = lastName;
    self.fullName = function () {
        return self.firstName + ' ' + self.lastName;
    };
};

var p = new Person('Sander', 'Rossel');
console.log(p.fullName());

So what happens when we call new Person(‘Sander’, ‘Rossel’)? First, two new instances of String are created, ‘Sander’ and ‘Rossel’.

Second, a new object is created. After that the object, representing a Person, gets three new properties, firstName and lastName, which are assigned the two strings, and the function fullName, for which a new function is instantiated. That last part is crucial, a new function instance is created every time you create a new person object. Now performance and memory wise this isn’t optimal. Let’s see how we can optimize this.

var Person = function (firstName, lastName) {
    var self = this;
    self.firstName = firstName;
    self.lastName = lastName;
};

var getFullName = function (person) {
    return person.firstName + ' ' + person.lastName;
};

var p = new Person('Sander', 'Rossel');
console.log(getFullName(p));

This time the function getFullName is created once and can be used for any instance of Person.

The benchmark

Don’t believe me? Let’s test that.

'use strict';

var benchmark = function(description, callback) {
    var start = new Date().getTime();
    for (var i = 0; i < 10000000; i++) {
        callback();
    }
    console.log(description + ' took: ' + (new Date().getTime() - start));
};

var Person = function (firstName, lastName) {
    var self = this;
    self.firstName = firstName;
    self.lastName = lastName;
    self.fullName = function () {
        return self.firstName + ' ' + self.lastName;
    };
};

var PersonNoFullName = function (firstName, lastName) {
    var self = this;
    self.firstName = firstName;
    self.lastName = lastName;
};

var getFullName = function (person) {
    return person.firstName + ' ' + person.lastName;
};

benchmark('Full name', function () {
    var p = new Person('Sander', 'Rossel');
    var n = p.fullName();
});

benchmark('No full name', function () {
    var p = new PersonNoFullName('Sander', 'Rossel');
    var n = getFullName(p);
});

That’s a bit of code, but what happens is that we create 10.000.000 (that’s ten million) instances of Person with the fullName function defined on the Person object and we create ten million instances of a Person without the fullName function and use the pre-defined getFullName function instead. Then we log the time both methods took.

It may surprise you, but the result I get differs greatly per browser. Here they are (times in milliseconds):

                IE      FF      Chrome
Full name:      3705    361     2805
No full name:   3121    21      222

What this shows is that Firefox is fastest by far and IE is, of course, really very slow, especially when it comes to the method without full name. All browsers are considerably faster (especially Chrome) using the getFullName method though.

Enter prototype

Now that we’ve seen that functions in your constructors aren’t really optimal, especially when they don’t use any internal state of an object, and that we’ve seen how to optimize that let’s look at a better way, prototype.

The use of an external function doesn’t feel right. Full name should be part of your Person object, but now we have to call some external function to get it. That’s where prototype comes in. Functions in JavaScript have a prototype property. Prototype defines static methods, like getFullName, and ‘pastes’ them on your objects through prototypal inheritance.

var PersonProto = function (firstName, lastName) {
    var self = this;
    self.firstName = firstName;
    self.lastName = lastName;
};

PersonProto.prototype.fullName = function () {
    return this.firstName + ' ' + this.lastName;
};

And that’s really all there is to it! We have now defined the fullName function on PersonProto’s prototype, which means every instance of PersonProto now gets the fullName function.

var p = new PersonProto('Sander', 'Rossel');
var n = p.fullName();

If we’d benchmark this we’d get about the same speed as we got earlier when using the getFullName function (really, try it).

To Prototype or not to Prototype…

You might be tempted to think it doesn’t matter whether you use a static method like getFullName or prototype, other than the manner in which you invoke the function (object.function() vs. function(object)). That isn’t true though, prototype has a few pros and cons compared to other methods. First of all, by using it, we’ve lost control over ‘this’. Earlier, when defining fullName in the constructor we could use ‘self’, which always points to the correct instance of Person. We’ve lost that benefit with prototype and ‘this’ is now dependent on the context in which the function was invoked. Below code will break.

var p = new PersonProto('Sander', 'Rossel');
console.log(p.fullName());
var fn = p.fullName;
console.log(fn());

While the following code will work just fine.

var p = new Person('Sander', 'Rossel');
console.log(p.fullName());
var fn = p.fullName;
console.log(fn());

It’s the same code on the outside, but fullName of Person points to ‘self’ while fullName of PersonProto points to this (which, in the second call, is ‘window’).

Another pro, maybe, is that prototypal functions cannot be deleted from an object (although they can be overwritten). The first bit will run fine and prints ‘Sander Rossel’, the second part will break.

var p = new PersonProto('Sander', 'Rossel');
delete p.fullName;
console.log(p.fullName());

// This will break.
// fullName is no longer defined after a delete.
var p = new Person('Sander', 'Rossel');
delete p.fullName;
console.log(p.fullName());

And remember that prototype objects are static, which means they’re shared by all instances of an object. You can overwrite the value per instance though.

PersonProto.prototype.friends = [];
var p1 = new PersonProto('Sander', 'Rossel');
var p2 = new PersonProto('Bill', 'Gates');
p1.friends.push(p2);
console.log(p1.friends[0].fullName() + ' is a friend of ' + p1.fullName());
console.log(p2.friends[0].fullName() + ' is a friend of ' + p2.fullName());

Guess what, because the friends array is static Bill Gates is now also a friend of himself, even though I only added him to my own friends.

Inheritance

One big pro to using prototype is inheritance. One object can inherit the prototype of another object. The ‘pseudoclassical’ way to do this is by copying the prototype object.

var Employee = function (firstName, lastName, salary) {
    var self = this;
    self.firstName = firstName;
    self.lastName = lastName;
    self.salary = salary;
};

Employee.prototype = PersonProto.prototype;

Employee.prototype.getSalary = function () {
    return this.fullName() + ' earns ' + this.salary;
};

So we have an Employee with a salary and, of course, a name. An Employee is actually just a Person with a salary. So we ‘inherit’ the prototype of PersonProto. We also define a new function on the prototype, getSalary. Unfortunately, while Employee now has the fullName function, this has some undesired side effects…

var e = new Employee('Sander', 'Rossel', 1000000); // I wish :-)
console.log(e.getSalary());

var p = new PersonProto('Sander', 'Rossel');
console.log(p.getSalary());

That’s right, PersonProto now also has a getSalary function! That’s because Employee.prototype == PersonProto.prototype. So once we add getSalary to Employee.prototype PersonProto now has it too.

We can fix this by creating a temporary constructor, assigning the prototype to the temporary constructor, instantiating an object using the temporary constructor and assigning that to the prototype of the inheriting object. Last, because a prototype is assigned to the constructor function, we must set the prototype’s constructor to the inheriting constructor.

var Temp = function () {};
Temp.prototype = PersonProto.prototype;
Employee.prototype = new Temp();
Employee.prototype.constructor = Employee;

Employee.prototype.getSalary = function () {
    return this.fullName() + ' earns ' + this.salary;
};

Alright, so I agree that’s pretty arcane! Luckily you can put this in a function so you only have to write it once.

var inherit = function (inheritor, inherited) {
    var Temp = function () {};
    Temp.prototype = inherited.prototype;
    inheritor.prototype = new Temp();
    inheritor.prototype.constructor = inheritor;
};
inherit(Employee, PersonProto);

And you can also see that Employee is actually also a PersonProto.

if (e instanceof Employee) {
    console.log('e is an instance of Employee.'); 
}

if (e instanceof PersonProto) {
    console.log('e is an instance of PersonProto.');
}

Object.create

Another method to create an object with a specific prototype is by using the Object.create function.

var o = Object.create(PersonProto.prototype);
o.firstName = 'Sander';
o.lastName = 'Rossel';
console.log(o.fullName());

So here o has the PersonProto prototype and o is of the type PersonProto. Now let’s use Object.create for inheritance like we’ve seen above (for this example I’ve created an Employee2 which is similar to Employee).

Employee2.prototype = Object.create(PersonProto.prototype);
Employee2.prototype.constructor = Employee2;

Employee2.prototype.getSalary = function () {
    return this.fullName() + ' earns ' + this.salary;
};

var e = new Employee2('Sander', 'Rossel', 1000000); // I wish :-)
console.log(e.getSalary());

And there you have it.

Prototype vs. __proto__

As I said before prototype kind of ‘glues’ the static functions to the object instances you create. This happens through the proto property each object instance has. Each instance of an object has a proto property defined, which is constructed using the constructor.prototype. So while object literals don’t have a prototype property they do have a proto property which you can use to dynamically extend the prototype of an object.

var p = {
    firstName: 'Sander',
    lastName: 'Rossel'
};

if (p.__proto__ === Object.prototype) {
    console.log('__proto__ points to the constructors prototype.');
}

// Highly discouraged!
p.__proto__.fullName = function () {
    return this.firstName + ' ' + this.lastName;
};

console.log(p.fullName());
delete p.fullName;
console.log(p.fullName());

So by adding fullName to o.proto we’ve actually added fullName to Object.prototype! That means ALL your objects now have a fullName function.

var i = 10;
console.log(i.fullName());

See why doing that is highly discouraged? It’s slow to boot. I just thought you should know about it.

Beware, fellow traveler!

So that’s it! I have some final remarks for you before you go and use this knowledge out in the wild.
Don’t change the prototype of built-in types such as Object and Array. You could do this to support new functionality in older browsers, but there are probably a few libraries that already do that for you.

Prototype can have a negative impact on performance. What happened when we called fullName on Employee? The JavaScript engine looks for fullName on the object, but could not find it. It then looked for fullName on the Employee prototype, but again couldn’t find it. It works its way down the prototype chain and looked in the PersonProto prototype next, where it found fullName and called it. You can imagine that having huge inheritance chains can be bad for performance (but why would you have huge chains anyway?).

Last, as I said before, you can use JavaScript without ever needing prototype. Likewise, you can inherit objects without the need for prototype. For example, you can create a function Employee that creates a Person, adds the salary property and the getSalary function, and returns that.

Wrap up

And here’s some additional reading. First, of course, we have JavaScript Succinctly, which explain the various types, objects and functions, including prototype and inheritance.
And if you have some money to spare I can recommend one of the following books: Object-Oriented JavaScript by Packt Publishing or The Principles Of Object-Oriented JavaScript by No Starch Press.

Happy coding!