0

I am new to JS and like other novice struggling to understand concept of THIS keyword in JS. In below snippet name is changed to value1 which I understand since its c object which is calling log function .

But not able to understand why setName function is not able to change value of name variable?

var c ={

name:"value",
log:function(){
    this.name="Value 1";
    console.log(this.name); // c object is invoking log function hence this refers to c obj

    var setName= function(newName){
        this.name=newName;
    }

    setName('Value 2'); // isn't log function calling setName
    console.log(this.name);
    }
}

c.log();
Sunny Sachdeva
  • 249
  • 2
  • 13
  • Did you read any documentation about `this`? Such as [MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/this). – Felix Kling Jun 23 '16 at 14:47
  • ^ read these links. `setName` is an unbound function, and within such a function, `this` refers to the global object (e. g. `window`). – le_m Jun 23 '16 at 14:48
  • The `this` inside the `setName` function is the window object, not your created object. The `this` inside your log function refers to the `c` object. You've defined setName INSIDE log, so the `this` in there is treated different as it's at a different conceptual level from `c`. – ManoDestra Jun 23 '16 at 14:48
  • SimIlar duplicate: http://stackoverflow.com/questions/7950564/this-in-javascript – le_m Jun 23 '16 at 14:50
  • Related [How to access the correct `this` / context inside a callback?](http://stackoverflow.com/q/20279484/218196) – Felix Kling Jun 23 '16 at 14:51

3 Answers3

1

Value of this is determined by how function is called.

setName is not having context of c object, it is having the global(window) context. Use Function#bind to specify that context.

var c = {
  name: "value",
  log: function() {
    this.name = "Value 1";
    console.log(this.name);
    var setName = function(newName) {
      this.name = newName;
    }.bind(this);
    setName('Value 2');
    console.log(this.name);
  }
};
c.log();
Rayon
  • 34,175
  • 4
  • 40
  • 65
1

This line:

var setName= function(newName){
    this.name=newName;
}

Will not neccessary reference the upper function, since your call to it was direct and the dunction is not a direct member of the upper function, something like: this.setName = function().... So it will refer to a new context.

To change the upper one you have to make another reference for it not using this, like:

var upperThis = this;
var setName= function(newName){
    upperThis.name=newName;
}
MoustafaS
  • 1,829
  • 11
  • 20
  • *"References the function setName itself. "* no it doesn't. `this` never refers to the function itself, unless you *explicilty* set it to do that. Also, just by looking at the function *definition* doesn't tell you what the value of `this` is going to be. You also need to look at the call. – Felix Kling Jun 23 '16 at 14:50
  • @FelixKling Your are absolutely right! What I meant is in that specific case it won't refer to the upper function object, it will refer to a new context. – MoustafaS Jun 23 '16 at 14:54
  • Then why don't you just say that ;) – Felix Kling Jun 23 '16 at 14:55
  • Doing the edit now ;) – MoustafaS Jun 23 '16 at 14:57
0

The function setName creates a new context, so it creates a new this. This would do the trick:

var that = this;
var setName= function(newName){
    that.name=newName;
}
wtfzn
  • 523
  • 5
  • 12