The this keyword refers to the execution context — but its value is not determined by where a function is defined. It depends on how the function is called.

Default Binding

In non-strict mode, plain function calls set this to the global object (window in browsers). In strict mode, this is undefined.

  function showThis() {
    console.log(this);
}
showThis(); // window (browser) or global (Node)
  

Implicit Binding

When a function is called as a method of an object, this is that object:

  let user = {
    name: 'Alice',
    greet() {
        console.log(`Hello, ${this.name}`);
    }
};

user.greet(); // 'Hello, Alice' — this = user

// Lost binding when method is extracted
let fn = user.greet;
fn(); // this is NOT user — default binding applies
  

Explicit Binding: call, apply, bind

Force this to a specific value:

  function greet(greeting) {
    console.log(`${greeting}, ${this.name}`);
}

let user = { name: 'Bob' };

greet.call(user, 'Hi');      // 'Hi, Bob' — args listed individually
greet.apply(user, ['Hello']); // 'Hello, Bob' — args as array

let boundGreet = greet.bind(user);
boundGreet('Hey'); // 'Hey, Bob' — permanently bound
  

new Binding

When using new, this is the newly created object:

  function Person(name) {
    this.name = name;
}

let p = new Person('Charlie');
console.log(p.name); // 'Charlie'
  

Arrow Functions

Arrow functions do not have their own this. They inherit this from the enclosing lexical scope:

  let timer = {
    seconds: 0,
    start() {
        setInterval(() => {
            this.seconds++; // this = timer (lexical)
            console.log(this.seconds);
        }, 1000);
    }
};

// Compare with regular function — this would be wrong
let broken = {
    seconds: 0,
    start() {
        setInterval(function() {
            this.seconds++; // this = window or undefined
        }, 1000);
    }
};
  

this in Event Handlers

  button.addEventListener('click', function() {
    console.log(this); // the button element
});

button.addEventListener('click', () => {
    console.log(this); // this from outer scope, NOT the button
});
  

Summary Table

Call style this value
Plain call global / undefined (strict)
obj.method() obj
call/apply/bind specified object
new Fn() new instance
Arrow function lexical this from outer scope

Understanding this is critical for object-oriented patterns, event handlers, and callbacks.