Skip to content
intermediatePhase 32 · JavaScript Fundamentals

this Keyword

Understand how this binding works in different execution contexts.

45m
0 problems
Topic Progress0%

Global this

Global this

In the Browser

// Global scope
console.log(this); // Window object

// In strict mode
'use strict';
console.log(this); // undefined

In Node.js

// Global scope
console.log(this); // {}

// Module scope
console.log(module.exports); // {}

Function Calls

function sayHello() {
  console.log(this);
}

sayHello(); // Window (non-strict) or undefined (strict)

// Call/Apply/Bind
sayHello.call({ name: 'John' }); // { name: 'John' }

this in Different Contexts

Context this value
Global Window/undefined
Object method Object
Function Window/undefined
Arrow function Lexical scope
Class constructor Instance
Event handler Element

Strict Mode

// Non-strict: this is Window
function test() {
  console.log(this); // Window
}

// Strict: this is undefined
'use strict';
function test() {
  console.log(this); // undefined
}

Object Methods

Object Methods

Object Method this

const person = {
  name: 'John',
  greet() {
    console.log(`Hello, ${this.name}`); // "John"
  }
};

person.greet(); // this is person

this Depends on Call

const person = {
  name: 'John',
  greet() {
    console.log(this.name);
  }
};

const anotherPerson = { name: 'Jane' };

person.greet();          // "John"
anotherPerson.greet = person.greet;
anotherPerson.greet();   // "Jane"

const greet = person.greet;
greet();                 // undefined (global)

Method Extraction Problem

const person = {
  name: 'John',
  greet() {
    console.log(`Hello, ${this.name}`);
  }
};

const greet = person.greet;
greet(); // "Hello, undefined" (this is wrong!)

// Solutions:
// 1. Bind
const boundGreet = person.greet.bind(person);
boundGreet(); // "Hello, John"

// 2. Arrow function in method
const person = {
  name: 'John',
  greet: () => {
    console.log(`Hello, ${this.name}`); // this is NOT person!
  }
};

// 3. Store reference
const person = {
  name: 'John',
  init() {
    this.greet = () => {
      console.log(`Hello, ${this.name}`);
    };
  }
};

Nested Objects

const obj = {
  name: 'outer',
  nested: {
    name: 'inner',
    greet() {
      console.log(this.name); // "inner"
    }
  }
};

obj.nested.greet(); // "inner" (this is nested)

Method Chaining

const calculator = {
  value: 0,
  add(n) {
    this.value += n;
    return this; // Enable chaining
  },
  subtract(n) {
    this.value -= n;
    return this;
  },
  result() {
    return this.value;
  }
};

calculator.add(5).subtract(2).result(); // 3

Arrow Functions and this

Arrow Functions and this

Lexical this

Arrow functions don't have their own 'this' - they inherit from the enclosing scope.

const person = {
  name: 'John',
  greet: () => {
    // 'this' is NOT person!
    console.log(this.name); // undefined
  }
};

person.greet(); // undefined

When to Use Arrow Functions

// Good: callbacks
setTimeout(() => {
  console.log(this.name); // Correct 'this'
}, 1000);

// Good: array methods
const numbers = [1, 2, 3];
numbers.map(n => n * 2);

// Bad: object methods
const obj = {
  name: 'John',
  greet: () => {
    console.log(this.name); // undefined
  }
};

Object Method Workaround

// Use regular function for methods
const person = {
  name: 'John',
  greet() {
    console.log(this.name); // "John"
  }
};

// Or use arrow in property with function
const person = {
  name: 'John',
  greet: function() {
    console.log(this.name); // "John"
  }
};

// Or define in constructor
function Person(name) {
  this.name = name;
  this.greet = () => {
    console.log(this.name);
  };
}

Class Example

class Timer {
  constructor() {
    this.seconds = 0;
  }
  
  start() {
    // Arrow function inherits 'this' from class
    this.interval = setInterval(() => {
      this.seconds++;
      console.log(this.seconds);
    }, 1000);
  }
  
  stop() {
    clearInterval(this.interval);
  }
}

Event Handlers

// Arrow function: this is not the element
button.addEventListener('click', () => {
  console.log(this); // Window, not button!
});

// Regular function: this is the element
button.addEventListener('click', function() {
  console.log(this); // button
  this.classList.add('active');
});

Summary Table

Feature Regular Function Arrow Function
Has own this Yes No
this binding Dynamic (call site) Lexical (enclosing)
Use for methods Yes No
Use for callbacks Depends Yes

Practice Problems

0/3solved
Build this Keyword Component

Create a reusable React component implementing this Keyword. Include proper state management and accessibility.

Solution
// Production-ready component with:
// - Proper TypeScript types
// - Accessibility (ARIA)
// - Error boundaries
// - Loading states
// - Memoization where needed
this Keyword Testing

Write unit and integration tests for this Keyword using React Testing Library.

Solution
// Test coverage:
// 1. Rendering tests
// 2. Interaction tests
// 3. Edge case tests
// 4. Accessibility tests
this Keyword Performance

Optimize this Keyword for performance. Consider memoization, code splitting, and bundle size.

Solution
// Optimization techniques:
// 1. React.memo / useMemo / useCallback
// 2. Code splitting with lazy()
// 3. Virtual scrolling for lists
// 4. Image lazy loading
// 5. Bundle analysis

Quiz

1. What is 'this' in a regular function call?

Question 1 options

2. What is 'this' in an object method?

Question 2 options

3. What is 'this' in an arrow function?

Question 3 options

4. When should you use a regular function over an arrow function?

Question 4 options

5. What does .bind() do?

Question 5 options

Flashcards

Question

What is 'this' in an object method?

Answer

'this' refers to the object that owns the method.

Question

How do arrow functions handle 'this'?

Answer

They inherit 'this' from the enclosing scope (lexical this), not from the call site.

Question

What is the problem with extracting methods from objects?

Answer

The method loses its 'this' context. Use .bind() or arrow functions to fix.

Question

When should you NOT use arrow functions for methods?

Answer

When you need 'this' to refer to the object, like in object literals and prototypes.

Question

What does .bind() return?

Answer

A new function with 'this' permanently bound to the specified value.

Revision Notes

Key Takeaways

  • 1.'this' depends on how a function is called, not where it's defined
  • 2.Object methods have 'this' pointing to the object
  • 3.Arrow functions inherit 'this' from enclosing scope
  • 4.Use .bind() to fix lost 'this' context
  • 5.Avoid arrow functions for object methods

Interview Tips

  • Explain how 'this' works in different contexts
  • Know the difference between regular and arrow functions
  • Understand method extraction and binding
  • Be able to fix 'this' issues in code

Cheat Sheet

this Keyword Cheat Sheet

this Values

Context this
Global Window/undefined
Object method Object
Regular function Window/undefined
Arrow function Lexical scope
Class constructor Instance
Event handler Element

Fixing this

// 1. Bind
const bound = method.bind(obj);

// 2. Arrow in constructor
function Person() {
  this.greet = () => this.name;
}

// 3. Store reference
const self = this;

Arrow vs Regular

// Arrow: lexical this
const obj = {
  greet: () => this.name // Not obj!
};

// Regular: own this
const obj = {
  greet() { return this.name; } // obj!
};