5

Hi i'm trying to call a function which is an attribute value in a JSON.

Getting different results in different scenarios

var x = 3;
var foo = {
    x: 2,
    inner: {
        x: 1,
        reValue: function() {
            return this.x
        }
    }
}

var go = foo.inner.reValue;

Case 1:

console.log(go()) // 3

Case 2:

console.log(foo.inner.reValue()) // 1

Can anyone explain case 1?

kingdaro
  • 9,102
  • 2
  • 29
  • 33
Nevin
  • 129
  • 1
  • 1
  • 6
  • Please properly format your question next time... – Jonas Wilms Apr 08 '18 at 09:29
  • In the first case, `this` refers to the window object, which has a variable `x=3`, while in the second case `this` is the `foo` object, where `x=2` – bugs Apr 08 '18 at 09:30

4 Answers4

3

Creating a variable in global scope, automatically assigns it to window, so:

 var x = 3;
 var go = foo.inner.reValue;
 go()

does the same as:

 window.x = 3;
 window.go = foo.inner.reValue;
 window.go();

And the last line will call go with the context (aka this) being window, therefore this.x will be window.x.

If a function is called on an object, such as in obj.myMethod() or the equivalent obj["myMethod"](), then ThisBinding is set to the object (obj in the example; §13.2.1). ~ How does the this keyword work?

Jonas Wilms
  • 106,571
  • 13
  • 98
  • 120
0

You should have a look at bind() to bind the context.

If you re-bind go to foo.inner, it behaves as intended:

go=go.bind(foo.inner)

Or initially:

var go = foo.inner.reValue.bind(foo.inner);

As long as you did not specify the context, the global context (in case of a browser this is window) is chosen per default.

So this refers in your example to window.x, which is 3

Thomas Junk
  • 5,296
  • 2
  • 25
  • 39
0

The value of this is determined based upon where the function was called. Here is an example:

let foo = {
  bar: this,
  baz: function() {
    console.log(this)
  }
}

console.log(foo.bar); // logs window
foo.baz();            // logs foo

let hey = foo.baz;

hey();                // logs window

A new value of this is created when a method is invoked on a object. Therefore, our first log logs window because we haven't invoked any method. However, our second example logs foo because now a method on foo is called and therefore the value of this inside the baz function is foo. You can usually derive the value of this taking the object left of the dot of the function which is called.

For example foo.baz(), foo is left of the dot of baz() so foo is the value of this.

The last example is a bit tricky. The function object gets stored inside the variable hey. Now when hey gets executed it will log window. This is because the value of this is determined when hey() gets executed. Because hey is a global variable it sits on the window object. Using the rule we just learned we can take the object left of the dot of hey(). This is window, because all variables on the global scope are window.variable.

If you fully want to understand the value of this you should also know how the execution context works in JS. Here is some information about that.

ralphtheninja
  • 107,622
  • 20
  • 101
  • 118
Willem van der Veen
  • 19,609
  • 11
  • 116
  • 113
-1

this.x may be "local" to the function by interpretation. remove the "this" to de-localize , but if that has trouble you may need to write in a way that disambiguates x.