4

I have the following structure Javacript es5-es6 and the controller class loses the reference in the class Get, I was already investigating but I can not find how to avoid losing the reference.

class Controller {
    constructor() {
        this.name = 'Test';
    }
    test() {
        console.log(1, this.name);
    }
}

referenceController = new Controller();
// working reference: console.log(1, 'Test');
referenceController.test();


class Get {
    method() {
        return {
            controller: referenceController.test
        }
    }
}

// Lost self reference: console.log(1, undefined)
new Get().method().controller() 
Alan Olivares
  • 336
  • 2
  • 13
  • 1
    `obj.test()` calls test as a **method**, with the syntax `context dot method`. Passing `obj.test` passes test as a reference to that **function,** without the context, and no longer as a method. You have to bind functions to the right context, because they don't know about `this`, or always call `obj.test` – Andy Ray Mar 30 '17 at 00:10

2 Answers2

7

In this section, you add the test function as a property of the returned object.

{
    controller: referenceController.test
}

Then, when you call it as a method of that object (method().controller()) this refers to the object, and the name property is read from the object.

You could bind the context to preserve the reference:

referenceController.test.bind(referenceController)
Alexander O'Mara
  • 58,688
  • 18
  • 163
  • 171
0

Your method function returns an object with key controller whose value is not a reference to the instance of the Controller class but a function that references this.

The this context of a method will be assigned to the object that it is attached to when it is invoked.

So new Get().method().controller()

Calls the method test where this is the value that new Get().method() resolves to which is:

{
  controller: referenceController.test
}

Hence it logs out undefined


Amend your Get class as follows:

class Controller {
    constructor() {
        this.name = 'Test';
    }
    test() {
        console.log(1, this.name);
    }
}

referenceController = new Controller();
// working reference: console.log(1, 'Test');
referenceController.test();

class Get {
    method() {
        return {
            controller: referenceController
        }
    }
}

// this logs out correctly
new Get().method().controller.test();

The above works because new Get().method().controller resolves to the Controller class instance referenceController that does have a property defined name with a value.

Pineda
  • 7,435
  • 3
  • 30
  • 45