Understanding the 'this' Keyword in JavaScript: Anonymous Functions vs Arrow Functions
Adam C. |

The meaning of this in JavaScript can be a bit confusing, especially when using anonymous functions and arrow functions.

Photo by Felicia Buitenwerf on Unsplash

When you use an anonymous function declared with the function keyword, the this keyword inside the function refers to the object that called the function. In other words, the this keyword is bound to the context of the function call.

Here's an example:

const myObj = {
 myMethod: function() {
   console.log(this);
 }
};
myObj.myMethod(); // Logs myObj object

In this example, when myObj.myMethod() is called, the this keyword inside the myMethod function refers to the myObj object.

On the other hand, when you use an arrow function, the this keyword is not bound to the context of the function call. Instead, the this keyword inside an arrow function is determined by the enclosing lexical scope. In other words, the this value is inherited from the context in which the arrow function is defined.

Here's an example:

const myObj = {
  myMethod: () => {
    console.log(this);
  }
};

myObj.myMethod(); // Logs the global object (window in a browser, global in Node.js)

In this example, even though myMethod is called as a method of myObj, the this keyword inside the arrow function is not bound to the myObj object. Instead, it refers to the global object, because that is the lexical scope in which the arrow function is defined.

So, in summary:

  • In an anonymous function declared with the function keyword, the this keyword is bound to the calling object.
  • In an arrow function, the this keyword is not bound to the calling object and is instead determined by the enclosing lexical scope.

Once we understand the behavior of the this keyword in JavaScript, we come to realize that converting anonymous functions to arrow functions is not always straightforward. For example, Knex query builder relies on anonymous functions to achieve the desired behavior, as shown below:

  .andWhere(function() {
    this.where("c.draft", false).orWhere("c.draft", null);
  })
  .andWhere(function() {
    this.where("c.is_deleted", false).orWhere("c.is_deleted", null);
  }) 

In this code, the function() keyword is used to define the anonymous functions for the andWhere calls. Within these functions, the this keyword refers to the Knex query builder object, which allows further chaining of query operations.

While ESLint may flag these anonymous functions as "unnamed-function" by the func-names rule, converting them to arrow functions could potentially break the intended logic of the Knex query builder. Therefore, it's important to consider the specific context and behavior when deciding whether to use an anonymous function or an arrow function.