Shaun Xu

The Sheep-Pen of the Shaun



Shaun, the author of this blog is a semi-geek, clumsy developer, passionate speaker and incapable architect with about 10 years’ experience in .NET and JavaScript. He hopes to prove that software development is art rather than manufacturing. He's into cloud computing platform and technologies (Windows Azure, Amazon and Aliyun) and right now, Shaun is being attracted by JavaScript (Angular.js and Node.js) and he likes it.

Shaun is working at Worktile Inc. as the chief architect for overall design and develop worktile, a web-based collaboration and task management tool, and lesschat, a real-time communication aggregation tool.


My Stats

  • Posts - 122
  • Comments - 554
  • Trackbacks - 0

Tag Cloud

Recent Comments

Recent Posts


Post Categories

Image Galleries

  • There are three functions under JavaScript Function object which are bind, call and apply. They are very useful when we need to pass the function as a variant but very confused. I'd like to try to explain them here with a sample code in Node.js environment.


    Pass Function as a Variant

    Assume we have a class named "Person" as below. The constructor accepts two parameters for the person's first name and last name. We also added a method named "say", which accepts one parameter then return a string with the person's full name and the parameter value. I also override the "toString" method so that it will return "[object Person]".

       1: var Person = function (firstName, lastName) {
       2:     this._firstName = firstName;
       3:     this._lastName = lastName;
       4: };
       6: Person.prototype.say = function (message) {
       7:     return '[' + this + ']: ' + this._firstName + ' ' + this._lastName + ' said: "' + message + '"';
       8: };
      10: Person.prototype.toString = function () {
      11:     return '[object Person]';
      12: };

    Then I initialized this class and invoke "say" as below.

       1: var shaunxu = new Person('Shaun', 'Xu');
       3: console.log("shaunxu.say('Hello world')");
       4: console.log(shaunxu.say('Hello world'));
       5: console.log();

    Let's execute it and as you can see the function was invoked without any problems.


    Now let's do something different. As you should know we can pass a function as a variant, just like string, number and Boolean, etc. So I will retrieve "say" function by its name (which is "say") and set into a local variant, then invoke this variant.

       1: var func = shaunxu['say'];
       2: console.log("func('Hello world')");
       3: console.log(func('Hello world'));
       4: console.log();

    The executing result was unexpected. Even I retrieved this function from the instance of my class "Person", when invoked you will find "_firstName" and "_lastName" were all undefined, and "this" was not my "Person" instance, instead it's "[object global]".



    Function Context

    The reason why we met the problem above is something I'd like call "Function Context". In JavaScript a function will be invoked with a certain context. When we invoke through "shaunxu.say()", "shaunxu" is the context of the function "say" with the local variants "_firstName" and "_lastName" populated.

    But when we linked this function to a local variant, the context of the original function was lost. So that when we invoked this variant, current environment, which is [object global] will be the context. But there is no "_firstName" and "_lastName" in this context. This is the reason why the function returned incorrect result.


    We can added "_firstName" and "_lastName" as the local variants and executed this function again and we will found it worked but was not used the name defined inside our class.

       1: _firstName = 'Kun';
       2: _lastName = 'Zhang';
       4: var func = shaunxu['say'];
       5: console.log("func('Hello world')");
       6: console.log(func('Hello world'));
       7: console.log();


    We assigned the value to the variants "_firstName" and "_lastName" without defined so that they will became members under the global context. The code only worked under the non-strict mode.


    Specify Context through Call() and Apply()

    Since the problem is that we lost the context of this function when invoked, we can use "call" and "apply" method of JavaScript Function to specify the right context then invoke. The first argument of "call" and "apply" is the context object, in this case it's our "shaunxu" variant. The following arguments are the calling parameters. The only different between "call" and "apply" is, you can pass parameters for following arguments to "call", while you can pass parameters as an array to "apply".

    Let's change our code to invoke "say" through "call" and "apply".

       1: var func = shaunxu['say'];
       3: console.log(", 'Hello world')");
       4: console.log(, 'Hello world'));
       5: console.log();
       7: console.log("func.apply(shaunxu, ['Hello world'])");
       8: console.log(func.apply(shaunxu, ['Hello world']));
       9: console.log();

    Then execute our application we will see the function was invoked under our instance even though from the local variant.



    Set Context through Bind()

    With "bind()" method, we can set the context of a function. So in the future we can invoke this function variant without specifying the context when invoked.

    In the code below I retrieved the function from its key ("say") and invoked the "bind" method to set "shaunxu" object as its context. Then invoke this function variant directly.

       1: var func = shaunxu['say'].bind(shaunxu);
       3: console.log("func.bind(); func('Hello world')");
       4: console.log(func('Hello world'));
       5: console.log();

    And we can see it returned correctly.


    By using "bind" we can set any object as the context of a function. This gives us extremely flexibility to extend our code. In the sample code below I bind my function to a new object with "_firstName" and "_lastName" members and it worked as we expected.

       1: var func = shaunxu['say'].bind({ _firstName: 'Ziyan', _lastName: 'Xu' });
       3: console.log("func.bind(); func('Hello world')");
       4: console.log(func('Hello world'));
       5: console.log();




    JavaScript is a very flexible language. Different from C#, we can assign a function to a variant and dealing with it later in JavaScript. But when invoke a function variant, we must pay attention to its context.

    We must understand once we assign a function into a variant the context of this function will be changed. It will be the calling function if our code was in a function, or global of it's in top level. When invoke this function variant we should specify correct context through "call" and "apply" method. Alternatively we should set the certain context through "bind".


    Hope this helps,


    All documents and related graphics, codes are provided "AS IS" without warranty of any kind.
    Copyright © Shaun Ziyan Xu. This work is licensed under the Creative Commons License.


    Gravatar # re: bind(), call() and apply() in JavaScript Function
    Posted by Shrikster on 12/17/2013 4:23 AM
    Thanks , finally simple short and clear explaining on
    call apply bind and function context (scope)
    Gravatar # re: bind(), call() and apply() in JavaScript Function
    Posted by kenoy on 3/21/2014 5:07 AM
    Excellent resource , understood , abt call and apply , easily.
    thnx a lot
    Gravatar # re: bind(), call() and apply() in JavaScript Function
    Posted by Bharat on 5/19/2015 10:33 PM
    Thank you, especially for the diagram where you show how the function is copied to the global scope. :)

    The example given is simple to understand and simple is good.
    Gravatar # re: bind(), call() and apply() in JavaScript Function
    Posted by Nihal on 8/11/2015 8:15 PM
    Thank you very much for the post. Exactly what i was looking for.
    Gravatar # re: bind(), call() and apply() in JavaScript Function
    Posted by mel on 6/27/2017 1:19 PM
    10/10 great post, learned much
    Post A Comment