Post

The Two Faces of 'this' in JavaScript

The Two Faces of 'this' in JavaScript

JavaScript’s this is like a chameleon - its identity changes based on its surroundings. Let’s dive into its true nature.

The Shape-Shifter

1
2
3
4
5
6
7
8
// The global wanderer
console.log(this); // Window or global

// The loyal companion
const ninja = {
  name: 'Shadow',
  strike() { return `${this.name} strikes!`; }
};

Lost in Translation

The most treacherous scenarios occur during context transitions:

1
2
3
4
5
6
7
8
const warrior = {
  name: 'Storm',
  attack() {
    setTimeout(function() {
      console.log(`${this.name} attacks!`); // Oops, this lost its way
    }, 1000);
  }
};

Arrow Functions: The Faithful Messenger

1
2
3
4
5
6
7
8
const archer = {
  name: 'Wind',
  shoot() {
    setTimeout(() => {
      console.log(`${this.name} shoots!`); // Arrow keeps its promise
    }, 1000);
  }
};

The DOM’s Special Rules

1
2
3
4
5
6
7
8
button.addEventListener('click', function() {
  this.classList.toggle('active'); // Browser's gift - 'this' is the button
});

button.addEventListener('click', () => {
  // Arrow function ignores the gift, keeps its own 'this'
  this.classList.toggle('active'); // Beware: 'this' isn't the button!
});

Modern Class: A Safe Haven

1
2
3
4
5
6
7
8
9
10
class Knight {
  constructor(name) {
    this.name = name;
    this.charge = () => `${this.name} charges forward!`;  // Bound forever
  }
  
  defend() {
    return `${this.name} raises shield!`;  // Class method, clear context
  }
}

The Golden Rules

  • Regular functions: this is decided by the caller
  • Arrow functions: this is inherited from birth
  • Methods: this is the object before the dot
  • Event handlers: Trust regular functions, doubt arrows

Remember: context is king, but arrow functions are loyal to their birthplace.

This post is licensed under CC BY 4.0 by the author.