1

actually im trying to run the following code:

var myObj = {
  subObj: {
    methodA: (parA) => {
      this.methodB(parA); //This is not working
    },
    methodB: (parB) => {
      console.log(parB);
    }
  }
}

myObj.subObj.methodA('Hello World');
i get the error "Uncaught TypeError: this.methodB is not a function".

Why am i getting this error? Isn't "methodB" in scope of methodA via 'this'?

Thank you very much

  • No, it is not scoped to the object. – Evert Jun 06 '20 at 19:18
  • 1
    Does this answer your question? [Methods in ES6 objects: using arrow functions](https://stackoverflow.com/questions/31095710/methods-in-es6-objects-using-arrow-functions) – VLAZ Jun 06 '20 at 19:26
  • Also relevant:[Self-references in object literals / initializers](https://stackoverflow.com/questions/4616202/self-references-in-object-literals-initializers) – VLAZ Jun 06 '20 at 19:27

3 Answers3

1

Arrow functions have special binding. The value of this in arrow functions is equivalent to the value of this where the function was defined(lexical scope). In this situation window(in browsers). To make your function work, use regular functions where this references the enclosing context:

var myObj = {
  subObj: {
    methodA: function (parA) {
      this.methodB(parA); //This is not working
    },
    methodB: function (parB) {
      console.log(parB);
    }
  }
}

myObj.subObj.methodA('Hello World');

More on this is explained here.

kimobrian254
  • 557
  • 3
  • 10
  • You can also use shorthand method syntax `methodA(parA)` instead of `methodA: function (parA)` – VLAZ Jun 06 '20 at 19:33
1

Arrow functions don't have separate this.

Hence doing

var myObj = {
  subObj: {
    methodA: (parA) => {
      this.methodB(parA); // `this` will always be window / outer context as arrow functions will not bind `this` at runtime.
    },
    methodB: (parB) => {
      console.log(parB);
    }
  }
}


myObj.subObj.methodA('Hello World'); // fails as `this.methodB` in your `methodA` is equivalent to `window.methodB` which is not present

is similar to doing:

var myObj = {
  subObj: {
    methodA: function(parA) {
      this.methodB(parA);
    },
    methodB: function(parB) {
      console.log(parB);
    }
  }
}

myObj.subObj.methodA.call(window || {}, 'Hello World');  // where window || {} is the lexical / outer scope to your function.

In the latter's case, things will work when you do the following:

myObj.subObj.methodA('Hello World');

Since normal functions use this of the caller and you call methodA as myObj.subObj.methodA, this = myObj.subObj. Hence this.methodB is available as it's equivalent to myObj.subObj.methodB

chiragrtr
  • 902
  • 4
  • 6
0

My guess would be, that it is because all of these are anonymous, non-scoped, non-instantiated objects and this actually refers to the window object.

Viktor Velev
  • 176
  • 1
  • 8