user3666112 user3666112 - 5 months ago 9
Javascript Question

How to make name accessible in this code

var hello = {
name: "Vishal",
speak: function(to){
return function (){
console.log(this.name+" says hello "+to);
}();
}
}


I call this function as -

hello.speak("Vinay");


Actual Output is

says hello to Vinay


Expected output is

Vishal says hello to Vinay


I know
hello.name
will resolve this but how to resolve it using
this
so that using
call
method or
apply
or
bind
method this could be resolved.

Answer

What is happening in your code:

You have binded a function with an object hello which in turn returns another function that outputs something. The outer function speak acts as a closure to the inner function. Here javascript behaves a little differently because of the way it compiles the code. The inner function will not recognise the this variable and rather pick the global this.name.

To resolve the issue you will have to do this:

var hello = {
    name: "Vishal",
    speak: function(to){ 

   //we tell this closure that this is to be taken from function scope and no the global scope
       var self = this; 
        return function (){ 
            console.log(self.name+" says hello "+to);
        }();
    }
}

hello.speak("Vinay");

Understanding use case bind

Bind:

Creates copy of the function with which bind is called. You can then pass on the object or the scope which you want to be associated with the this keyword.

Example:

var hello = {
    name: "Vishal",
    speak: function(to){
        return function (){ 
            console.log(this.name+" says hello "+to);
        };
    }
}

var speakTo = hello.speak("Vinay");


var speakToCall = speakTo.bind(hello); //will give you the desired output.

speakToCall();

Now, this is not the real use case of bind, call or apply. It was just to show you how your functionality can be achieved using bind.

Real use case can be something like this:

Use Case:

When you have multiple objects like:

var a = {
    firstname: "rahul",
    lastname: "arora",
    getFullName: function(){
        return this.firstname + ' ' +  this.lastname;
    }
}

//Another object with same properties but without the function
var b = {
    firstname: "Micheal",
    lastname: "Angelo",
}

//Rather than defining that function again in the object 'b' you can use bind, call or apply to get the desired output.

console.log(a.getFullName.call(b)); // will output Micheal Angelo which is associated to b

I hope it helps.

Comments