The problem in example 1 is 'this' referring to the global name instead of the myName object.
I understand the use of bind() in setting the value of this to a specific object, so it solves the problem in example 1, but why does this problem occur in the first place? Is it just the way Javascript was created?
I'm also wondering why example 3 solves the issue and the difference between example 2 and 3.
this.name = "John"
var myName = {
name: "Tom",
getName: function() {
return this.name
}
}
var storeMyName = myName.getName; // example 1
var storeMyName2 = myName.getName.bind(myName); // example 2
var storeMyName3 = myName.getName(); // example 3
console.log("example 1: " + storeMyName()); // doesn't work
console.log("example 2: " + storeMyName2()); // works
console.log("example 3: " + storeMyName3); // works
So, when you execute
var storeMyName = myName.getName;
the first time, it takes the globalname
( this.name = "John" )When you use
bind()
function, it starts referring to the name defined in the current closure ( myName in this case ) and hence printsTom
Third time, since the function is called right away its scope is within its own local object and thus prints the value in the closure
Tom
The value of
this
is determined by how a function is called. If it is you who calls the function then there is usually no need to use.bind
, since you have control over how to call the function, and therefore itsthis
value.However, often it is not you who calls the function. Functions are passed to other functions as callbacks and event handlers. They are called by other code and you have no control over how the function is called, and therefore cannot control what
this
will refer to.If your function requires
this
to be set to a specific value and you are not the one calling the function, you need to.bind
the function to a specificthis
value.In other words:
.bind
allows you to set the value ofthis
without calling the function now.Here is comparison of referring to/calling functions:
Example 1/2 and 3 couldn't be more different.
storeMyName
andstoreMyName2
contain functions, which are called in the future, whereasstoreMyName3
contains the result of callingmyName.getName()
at that moment.Further reading material:
An analogy i like, which i have never seen anywhere: Let say you have a foo object with a
bar
function. When you are binding the bar function to another variable (or passing it as a function parameter, which is more common case with callbacks), you are not binding/passing the function with his enclosing object but only the "nude" function. Hence with the "nude" function,this
means the global object.A small demo
bound
just point to thefunction(){return this.foo;}
Bind is the mechanism by which you can change the context(here your default context is global) of execution.
Based on your example -
From above line is you are executing
storeMyName
function in global context, so for this executionthis.name
will be top line(i.e. global one / "John").For above line you are Explicitly changing the context of execution for
storeMyName2
function(by saying that i don't want to execute this function as global function i want to execute this function in context ofmyName
object, so in this casethis.name
will be "Tom")And for this above line you are just executing function on
myName
object context, more importantly you are not executing thestoreMyName3
and that's why its context is not global one.