Search This Blog

Sunday, March 4, 2018

What is call() , apply() and bind() in JavaScript ?

As functions are also Objects in JavaScript, these 3 methods are used to control the invocation of the function. call() and apply() were introduced
in ECMAScript 3 while bind() was added as part of ECMAScript 5.


call() or Function.prototype.call():

    consider following code snippet

        var obj = {name:"John"};
        var howDoYouDo = function(a,b){
            return "How are you "+ this.name + ", welcome to " + a + "," + b;
        };
        console.log(howDoYouDo.call(obj,"Pune","Maharashtra"));

    output:
        How are you John, welcome to Pune,Maharashtra


    we are using call() method on howDoYouDo(),first argument sets the "this" value, other two arguments are parameters of  greeting function in corresponding order.


apply() or Function.prototype.apply():

    consider following code snippet

        var obj = {name:"merry"};
        var howDoYouDo = function(a,b){
            return "How are you "+ this.name + ", welcome to " + a + "," + b;
        };
        var args = ["Mumbai","Maharshtra"];
        console.log(howDoYouDo.apply(obj,args));

    output:
        How are you merry, welcome to Mumbai,Maharshtra

    we are using apply() method on howDoYouDo(),first argument sets the "this" value ,other two arguments are parameters of  howDoYouDo() function in corresponding order
    passed as an array.

bind() or Function.prototype.bind():

    consider following code snippet

        var obj = {name:"saucy"};
        var howDoYouDo = function(a,b){
            return "How are you "+ this.name + ", welcome to " + a + "," + b;
        };
        var bound = howDoYouDo.bind(obj);
        console.log(bound("Nagpur","Maharshtra"));

    output:
        How are you saucy, welcome to Nagpur,Maharshtra

    Here we are creating bound function to which we passed 'this' the context but bound function can be invoked seperately at latter moment.

    Lets consider one more example for bind() function

        var getUserComments = function(callback) {
            var numOfCommets = 34;
            callback({ comments: numOfCommets });
        };
        var User = {
            fullName: 'John Black',
            print: function() {
                getUserComments(function(data) {
                        console.log(this.fullName + ' made ' + data.comments + ' comments');
                });
            }
        };
        User.print();

    output:
        undefined made 34 comments

    Here this.fullName is having value undefined inside getUserComments() function basically it is not getting desired value of 'this'.

        Lets see how we can use bind() here to fix problem

        var getUserComments = function(callback) {
                    var numOfCommets = 34;
                    callback({ comments: numOfCommets });
                };

        var User = {
            fullName: 'John Black',
            print: function() {
            console.log(this);
            getUserComments(function(data) {
                console.log(this.fullName + ' made ' + data.comments + ' comments');
            }.bind(this));
            }
        };
        User.print();


    output:
        {fullName: "John Black", print: ƒ}

        John Black made 34 comments

    Here when we are doing 'console.log(this);' inside 'print()' method ,we see that by passing it to bind on function getUserComments() ,'this.fullName' can get desired value.


How to define private property using bind in a javascript class ?
    There are no private, public or protected keywords in current ECMAScript 6 specification but we can use bind() function to define a private method/property in class.
  
    Inside democlass.js

        function privateFunc() {
            console.log("My property: " + this.property);
        }
        class MyClass {
            constructor() {
            this.property = "property_value";
            }
            callPrivateFunc() {
            var boundPrivateFunc = privateFunc.bind(this);
            boundPrivateFunc();
            }
        }
        module.exports = MyClass;  

    Inside demo.js

        var dc = require('./democlass');

        var cls =new dc();
        cls.callPrivateFunc();
        cls.privateFunc();  

     Here in 'MyClass' we are writing a method  callPrivateFunc() in which we are binding function defined outside class 'privateFunc()' to this including this module in demo.js
     Inside demo.js we are calling 'callPrivateFunc()' method of class and privateFunc() method defined outside class
    for our attempt to call 'privateFunc()' method we get an error as follows

        TypeError: cls.privateFunc is not a function

    but calling class method succeed we get result too

        My property: property_value
  
      this way we defined private method in class.

Note : print without using console ?

     process.stdout.write("hello: ");
 


No comments:

Post a Comment