2

So i was just testing how the value of this is affected inside an ES6 class method.

Can someone explain me why the value of this inside the inner function undefined in below code?

class testingThis {
  outerFunc() {
    console.log("the value of this in outerFunc: ", this);
    function innerFunc() {
      console.log("value of this in innerFunc: ", this);
    }
    innerFunc();
  }
};

var newTest = new testingThis();
newTest.outerFunc();

Why is the value this not preserved in ES6 (not necessarily ES6 i guess) methods but is preserved in usual functions (like below):

function a() {
  console.log("this outer: ", this)

  function b() {
    console.log("this inner: ", this)
  }
  b();
};
a();

Both inner and outer this in above code have the same value (window).

D_S_X
  • 848
  • 2
  • 8
  • 27

1 Answers1

1

ES6 class are automatically in strict mode.

That means that any plain function call sets the value of this to undefined within that function. That's all you're seeing.

FYI, this a strict mode feature, and the only involvement of ES6 is that it automatically puts class definitions into strict mode.


In strict mode, any plain function call sets this inside that function to undefined.

When not in strict mode, any plain function call sets this to the global object which, in a browser, is the window object.


The new part of your question is two plain function calls, not in strict mode, that both set this to the global object. It's not "preserving" the value of this. It's setting it to the global object in both function calls.

jfriend00
  • 580,699
  • 78
  • 809
  • 825
  • ah okay .. if I remove the "strict" mode would it show the same `this`? – D_S_X Sep 23 '19 at 14:40
  • 1
    @VSX - You can't remove strict mode in ES6 class definitions. Even if you did remove strict mode, `this` would just be set to the `global` object. It's a fact in Javascript that `this` is changed when you call a function. If you want `this` to be the object, then make `innerFunc` be a method or call it with `.call(this)`. FYI, `this` is never preserved when you call another function. It's always set to some value based on how the function is called. – jfriend00 Sep 23 '19 at 14:40
  • @VSX And even if you could, the answer is no. It would be `window` – Keith Sep 23 '19 at 14:41
  • @jfriend00 kindly checkout the updated post ... my main doubt is why working of `this` in a function nested inside ES6 class method different from the usual nested functions. – D_S_X Sep 23 '19 at 14:53
  • @VSX because you're comparing apples and oranges. In your second example, the outer function is also not a method, so `this` is `window` for both, as jfriend00 has already stated. It has nothing to do with "preservation", it's just that `a()` and `b()` are called without a context object. – Patrick Roberts Sep 23 '19 at 14:55
  • @VSX - As I say in my answer a plain function call, when not in strict mode, sets `this` to the global object (which is a browser is `window`) and separately, when in strict mode, sets it to `undefined`. So, all the new part of your question is seeing is two plain function calls, not in strict mode, that both set `this` to the global object. It's not "preserving" the value of `this`. It's setting it to the global object in both function calls. – jfriend00 Sep 23 '19 at 15:04
  • @jfriend00 thanks that explains it. So if the 2 nested functions (the 2nd part of question) were somehow in `strict` mode, the inner `this` would be `undefined` and outer `this` would equal `window` object? – D_S_X Sep 23 '19 at 15:14
  • 1
    @VSX - If they were both defined in `strict` mode and they were both called as normal functions, then `this` in both of them would be `undefined`. The main takeway here should be that you don't use `this` in a function unless the function is called in a way that makes that value of `this` be meaningful and known. See [Ways the value of `this` is controlled](https://stackoverflow.com/questions/28016664/when-you-pass-this-as-an-argument/28016676#28016676) for more info. – jfriend00 Sep 23 '19 at 15:21