To understand this issue, you have to understand how Javascript sets the value of this
in a function call.
There's a summary of all the methods here: When you pass 'this' as an argument
For your particular case, when you do this:
var testing = obj.value.getName;
You now have a reference to the getName
function. You no longer have any connection at all to obj.value
. So, test()
just calls getName
as an ordinary function. In Javascript when an ordinary function call is made, then the value of this
will be either the global object (window
in a browser) or in strict mode, it will be undefined.
In your case, this
becomes the window
object so this.name
is window.name
which points to the global variable name
and thus you get the result 'Gerorge Thomas'.
In fact, if you run your code in strict
mode, it will cause an error which is, in fact, one of the benefits of strict mode that it points out accidental errors like this.
On the other hand, if you execute a function with the form of obj.method()
, then this
is set to be obj
. So, when you do:
obj.value.getName()
that is equivalent to:
var o = obj.value;
o.getName()
which is the obj.method()
form of calling a function which will set the this
pointer to be the object, which in this case is obj.value
.
It is possible to work around this issue in a couple of ways. Here's an example of working around it using .bind()
.
var name = 'Gerorge Thomas';
var obj = {
name: 'Cinderella',
value: {
name: 'HocusPocus',
getName: function() {
return this.name;
}
}
};
document.write( obj.value.getName() + "<br>");
var testing = obj.value.getName.bind(obj.value);
document.write(testing());