Curriculum Series

How does the this keyword work in JavaScript?

How does the this keyword work in JavaScript?

How does the this keyword work in JavaScript?

JavaScript

this keyword

The this keyword in JavaScript is a special keyword that refers to the current context in which code is being executed. Think of it as a reference to the "owner" of the currently executing code.

The this keyword allows you to reuse functions with different contexts.

I'll break down each scenario in more detail to help you understand how this behaves in different contexts.

Global Context & Strict Mode

JAVASCRIPT
1function showThis() {
2 console.log(this);
3}
4
5// Call site 1: Direct invocation
6showThis(); // Output: Window {...}
7// WHY: When a function is called without any context (not as a method),
8// 'this' defaults to the global object (Window in browsers)
9
10// Call site 2: Strict mode
11('use strict');
12function strictShowThis() {
13 console.log(this);
14}
15strictShowThis(); // Output: undefined
16// WHY: Strict mode changes this behavior to prevent accidental global object access.
17// It makes 'this' undefined instead of defaulting to global object.

Object Method Context

JAVASCRIPT
1const person = {
2 name: 'John',
3 sayHi: function () {
4 console.log('Hi, I am ' + this.name);
5 },
6};
7
8// Call site 1: Method invocation
9person.sayHi(); // Output: "Hi, I am John"
10// WHY: When a method is called directly on an object, 'this' binds to that object.
11// The call site shows person.sayHi(), so JavaScript knows to bind 'this' to person.
12
13// Call site 2: Function reference
14const greet = person.sayHi;
15greet(); // Output: "Hi, I am undefined"
16// WHY: We've lost the object context! When we assign the function to a new variable,
17// we're just getting the function itself, without its original object binding.
18// The call site is now just greet(), so 'this' defaults to global/undefined.

Constructor Functions

JAVASCRIPT
1function User(name) {
2 this.name = name;
3 this.sayName = function () {
4 console.log('My name is ' + this.name);
5 };
6}
7
8// Call site 1: With 'new' keyword
9const user1 = new User('John');
10user1.sayName(); // Output: "My name is John"
11// WHY: The 'new' keyword creates a new empty object and makes 'this' point to it.
12// It's like saying "create a new context for this function"
13
14// Call site 2: Without 'new' (wrong!)
15const user2 = User('Jane');
16// WHY: Without 'new', it's a regular function call, so 'this' points to global
17// This accidentally sets window.name = "Jane" - a common mistake!

Event Listeners

JAVASCRIPT
1const button = document.createElement('button');
2
3button.addEventListener('click', function () {
4 console.log(this); // Output: <button> element
5});
6// WHY: DOM events automatically bind 'this' to the element that triggered the event.
7// This is built into how addEventListener works.
8
9button.addEventListener('click', () => {
10 console.log(this); // Output: Window or parent scope's 'this'
11});
12// WHY: Arrow functions are different! They inherit 'this' from their enclosing scope.
13// They don't get their own 'this' binding.

Explicit Binding (bind/call/apply)

JAVASCRIPT
1function introduce() {
2 console.log('I am ' + this.name);
3}
4
5const person1 = { name: 'John' };
6const person2 = { name: 'Jane' };
7
8// Call site 1: Using call/apply
9introduce.call(person1); // Output: "I am John"
10introduce.apply(person2); // Output: "I am Jane"
11// WHY: call/apply let you explicitly set what 'this' should be.
12// It's like saying "run this function, but pretend it belongs to this object"
13
14// Call site 2: Using bind
15const introducePerson1 = introduce.bind(person1);
16introducePerson1(); // Output: "I am John"
17// WHY: bind creates a new function with 'this' permanently set to the specified object.
18// It's like creating a copy of the function that always remembers its context.

Key Points

  • JavaScript determines this at runtime based on the call site (how the function is called)
  • The value of this is not determined by where the function is defined, but by how it's called
  • Arrow functions are special - they inherit this from their surrounding scope
  • Explicit binding methods (call, apply, bind) let you control what this refers to
  • The new keyword creates a fresh context, making this point to the new object

This design allows for flexible function reuse and method borrowing, but it can also lead to confusion if you're not careful about how functions are called.

Finished reading?

Mark this topic as solved to track your progress.