Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How does Javascript evaluate "this"?

I am trying to understand some basic javascript .

I have the following snippet. We have the name variable which in both cases are referenced over getName Method.

First alert outputs HocusPocus, while the second one outputs GeorgeThomas. But I do not understand how this refers to name in this case

    var name = 'Gerorge Thomas';
    var obj = {
       name: 'Cinderella',
       value: {
          name: 'HocusPocus',
          getName: function() {
             return this.name;
          }
       }
    };
    
   alert( obj.value.getName() );
   var testing = obj.value.getName; 
   alert(testing());
like image 998
deroccha Avatar asked Jul 18 '26 00:07

deroccha


1 Answers

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());
like image 50
jfriend00 Avatar answered Jul 20 '26 13:07

jfriend00