3

I am having a problem understanding why the following does not work. I looked at the other suggested answers and none of them addresses this clearly in the context of a new class object.

Given the code below:

class Example1 {
  constructor(v1) {
    this.v1 = v1;
  }

  method1() {
    console.log("v1 value = ",this.v1)
  }
}

const example1 = new Example1("value1");
const alias1 = example1.method1;

example1.method1();
alias1();

When I call alias1(), why is this undefined?

Three D Fish
  • 114
  • 7
  • [How does the “this” keyword work?](https://stackoverflow.com/questions/3127429) – adiga Sep 30 '19 at 18:28
  • Short answer, it depends on how you call it. Unless you use arrow function, where it becomes the outer function's `this`. See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/this – Juan Mendes Sep 30 '19 at 18:56

2 Answers2

3

Its because the context of this changes when you call the alias1 (method1) just as a regular function instead of calling it on object.

When you call it on the object then the context of this is that object and in your case that context is lost and is either undefined or it falls back to the context of the global object (window in browsers) depending on the strict mode

You can set the context for this inside the alias using bind method to any object or you can define it inside some other object and that use that object to call it.

class Example1 {
  constructor(v1) {
    this.v1 = v1;
  }

  method1() {
    console.log("v1 value = ", this.v1)
  }
}

const example1 = new Example1("value1");
example1.method1();

const alias = example1.method1;
const alias1 = alias.bind(example1);
alias1();

const example2 = {v1: 'foo', alias}
example2.alias();
Nenad Vracar
  • 102,378
  • 14
  • 116
  • 136
2

Because this refers to method1 which does not have a v1 ,

You can use bind in the constructor :

Bind creates a new function that will have this set to the first parameter passed to bind().

class Example1 {
  constructor(v1) {
    this.v1 = v1;

    this.method1 = this.method1.bind(this);
  }

  method1() {
    console.log("v1 value = ", this.v1)
  }
}

const example1 = new Example1("value1");
const alias1 = example1.method1;

example1.method1();
alias1();
Taki
  • 15,354
  • 3
  • 20
  • 39