skip to Main Content

So as I am reading on the execution context in javascript and how does it works, everything seemed fine until I tried some examples on the this value of callback arrow functions.

const printCard = function () {
  this.signatories.forEach((signatory) =>
    console.log(this) /* expected to return signatories, returned messageConfig */
  );
};

const messageConfig = {
  closing: {
    Thor: "Admiration, respect, and love",
    Loki: "Your son",
  },
  signatories: ["Thor", "Loki"],
};

printCard.call(messageConfig);

Here since forEach is prototypal method of signatories, I expected the callback (the arrow function) to automatically take the this value from the enclosing context (forEach in this case). However, it seemed to return the messageConfig which reminds me of lexical scoping a little bit.

2

Answers


  1. An arrow function just borrows this and arguments from the outer scope (it doesn’t have own). The outer scope is printCard() which is called with this = messageConfig, and arguments arg1 and arg2. You can access the array with this.signatories or use the third argument of forEach() which is the array of being iterated.

    Arrow functions are useful as callbacks inside methods since you have this inside them as an instance a method is called on, so no need in bind/call/apply/self as with a usual function.

    const printCard = function () {
      this.signatories.forEach((signatory, i, arr) => {
        console.log(arguments);
        console.log(this.signatories);
        console.log(arr);
      });
    };
    
    const messageConfig = {
      closing: {
        Thor: "Admiration, respect, and love",
        Loki: "Your son",
      },
      signatories: ["Thor", "Loki"],
    };
    
    printCard.call(messageConfig, 'arg1', 'arg2');
    Login or Signup to reply.
  2. Array.prototype.forEach() doesn’t pass a this context to its callback function. It passes the array it’s looping over as the third argument. So if you want to get signatories, use

    const printCard = function () {
      this.signatories.forEach((signatory, i, signatories) =>
        console.log(signatories);
      );
    };
    

    Also, arrow functions don’t accept a passed this context. They inherit the context from the defining scope. Since you’re binding the context to messageConfig when you use printCard.call(), that’s the value of this in printCard() and also the callback function.

    If you were to change the callback function to a regular function, this would be the window object in a browser, or the global object in node.js, unless the code is in strict mode.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search