DEV Community

Amir Ehsan Ahmadzadeh
Amir Ehsan Ahmadzadeh

Posted on

Why 'this' in JavaScript Differs from Other OOP Languages

One of the most confusing aspects of JavaScript for me was understanding how the this keyword works.

The this keyword in JavaScript behaves differently from OOP languages like C#, Java, or Python (where the equivalent is self) because of how this is determined. In those languages, this consistently refers to the current instance of the class or object. In JavaScript, however, this is more dynamic and its value depends on how and where a function is invoked.

With that in mind, I decided to create a summary of the different scenarios where the behavior of this can vary. Here's the breakdown:


1. Global Context

Non-Strict Mode:

  • this refers to the global object (window in browsers, global in Node.js).
console.log(this); // `window` or `global`
Enter fullscreen mode Exit fullscreen mode

Strict Mode:

  • this is undefined.
"use strict";
console.log(this); // undefined
Enter fullscreen mode Exit fullscreen mode

2. Inside a Function

Regular Function:

  • In non-strict mode, this refers to the global object.
  • In strict mode, this is undefined.
function myFunction() {
    console.log(this);
}
myFunction(); // `window` (non-strict), undefined (strict)
Enter fullscreen mode Exit fullscreen mode

3. As a Method of an Object

  • When a function is called as a method of an object, this refers to the object that owns the method.
const obj = {
    name: "JavaScript",
    greet() {
        console.log(this.name); // `this` refers to `obj`
    }
};
obj.greet(); // Output: "JavaScript"
Enter fullscreen mode Exit fullscreen mode

4. Arrow Functions

  • Arrow functions do not have their own this. Instead, they inherit this from their lexical scope (the surrounding context).
const obj = {
    name: "JavaScript",
    arrowFunc: () => {
        console.log(this.name); // `this` is inherited from the global scope
    }
};
obj.arrowFunc(); // undefined (in browsers, `this` is `window`)

function outer() {
    const arrow = () => console.log(this);
    arrow(); // Inherits `this` from `outer`'s context
}
outer();
Enter fullscreen mode Exit fullscreen mode

5. In a Constructor

  • In a constructor function or class, this refers to the instance being created.
class Person {
    constructor(name) {
        this.name = name;
    }
    greet() {
        console.log(`Hello, ${this.name}`);
    }
}

const person = new Person("Alice");
person.greet(); // Output: Hello, Alice
Enter fullscreen mode Exit fullscreen mode

6. Explicit Binding (call, apply, bind)

In JavaScript, functions are objects and have methods like call, apply, and bind, which let you explicitly set the value of this.

call and apply:

  • Invoke the function with a specified this value.
  • Difference: call accepts arguments as a comma-separated list; apply takes an array.
function greet(greeting) {
    console.log(`${greeting}, ${this.name}`);
}

const user = { name: "Alice" };
greet.call(user, "Hello"); // Output: Hello, Alice
greet.apply(user, ["Hi"]); // Output: Hi, Alice
Enter fullscreen mode Exit fullscreen mode

bind:

  • Returns a new function with this permanently bound to the specified value.
const boundGreet = greet.bind(user);
boundGreet("Hello"); // Output: Hello, Alice
Enter fullscreen mode Exit fullscreen mode

7. In an Event Listener

Regular Function:

  • this refers to the element that triggered the event.
const button = document.querySelector("button");
button.addEventListener("click", function () {
    console.log(this); // The button element
});
Enter fullscreen mode Exit fullscreen mode

Arrow Function:

  • this inherits from the surrounding scope, not the element.
button.addEventListener("click", () => {
    console.log(this); // `this` depends on where the arrow function is defined
});
Enter fullscreen mode Exit fullscreen mode

8. Inside setTimeout or setInterval

Regular Function:

  • this defaults to the global object (window).
setTimeout(function () {
    console.log(this); // `window` in browsers
}, 1000);
Enter fullscreen mode Exit fullscreen mode

Arrow Function:

  • Inherits this from its lexical scope.
setTimeout(() => {
    console.log(this); // Inherits `this` from the surrounding context
}, 1000);
Enter fullscreen mode Exit fullscreen mode

9. In Classes

  • Inside a class method, this refers to the class instance.
class MyClass {
    constructor(name) {
        this.name = name;
    }

    sayName() {
        console.log(this.name);
    }
}

const obj = new MyClass("JavaScript");
obj.sayName(); // Output: JavaScript
Enter fullscreen mode Exit fullscreen mode

10. Losing Context (Method Extraction)

When a method is assigned to a variable or passed as a callback, this can lose its binding.

const obj = {
    name: "JavaScript",
    greet() {
        console.log(this.name);
    }
};

const greet = obj.greet;
greet(); // undefined (`this` is no longer bound to `obj`)
Enter fullscreen mode Exit fullscreen mode

Solutions:

  1. Use bind:
   const boundGreet = obj.greet.bind(obj);
   boundGreet(); // Output: JavaScript
Enter fullscreen mode Exit fullscreen mode
  1. Use an Arrow Function:
   const obj = {
       name: "JavaScript",
       greet: () => console.log(this.name) // `this` is inherited lexically
   };
   obj.greet(); // Output depends on outer scope
Enter fullscreen mode Exit fullscreen mode

11. In new Keyword Usage

When you use new with a function or class, this refers to the newly created object.

function MyConstructor() {
    this.name = "New Object";
}
const instance = new MyConstructor();
console.log(instance.name); // Output: New Object
Enter fullscreen mode Exit fullscreen mode

Summary

Context this Refers To
Global (non-strict) Global object (window/global).
Global (strict) undefined.
Object Method The object that owns the method.
Arrow Function Inherits this from the enclosing context.
Constructor/Class The instance being created.
call, apply, bind Explicitly defined value.
Event Listener The element that triggered the event.
setTimeout/Interval Global object or inherited context (arrow).
new Keyword The newly created object.

Top comments (0)