29
let role = {
    test: (variable) => {
        // How do I call toLog(variable) from here?
    },
    toLog: (variable) => {
        console.log(variable);
    }
};

I'd like to call the toLog() function within the test() function but I'm unaware how to.

sleepless_in_seattle
  • 2,132
  • 4
  • 24
  • 35
  • 4
    `role.toLog()` or use a class so you can simply use `this.toLog()` – Ties Dec 25 '16 at 21:15
  • 4
    [Don't use arrow functions where you don't need them!](http://stackoverflow.com/q/34361379/1048572) With method syntax (in the object literal) you could just invoke `this.toLog` as usual. – Bergi Dec 25 '16 at 22:18

2 Answers2

45

Standard JS functions use dynamic binding, this is dependent on who's calling the method on runtime, so if we call it using role.test(), it will bind this to role.

Arrow functions bind this to the current context. For example, if the code was writtern in the browser's console, this is bound to the window object. This is called static lexical binding, which means binding this to the closure it was defined in.

If you won't use arrow functions, this will point to the object itself when called by role:

const role = {
    test(variable){
        this.toLog(variable);
    },
    toLog(variable) {
        console.log(variable);
    }
};

role.test(5);

In this case, we don't want to bind this to the outer context, so we'll skip the static binding in favor of the dynamic one.

However, if we'll use this method as a callback, dynamic binding will change this according to who's running the method. To prevent that, we'll have to use bind to create an explicit static binding to role.

const role = {
  test(variable) {
      this.toLog(variable);
    },
    toLog(variable) {
      console.log(variable);
    }
};

let test = role.test;

try {
  test(20); // will throw an error - this.toLog is not a function - because this points to window
} catch (e) {
  console.log(e);
}

test = role.test.bind(role);

test(25); // will work because it's staticly binded to role
Ori Drori
  • 183,571
  • 29
  • 224
  • 209
2

Since you are using arrow functions, using this here will not work but you have your object referenced as role so you can call the function as role.toLog from your another function i.e. test as shown below

let role = {
    test: (variable) => {
        // How do I call toLog(variable) from here?
        role.toLog(`${variable} from test`);
    },
    toLog: (variable) => {
        console.log(variable);
    }
};

role.test('hello world');
Varun Sukheja
  • 6,170
  • 5
  • 51
  • 93