Javascript's `this` Keyword: Regular Functions vs Arrow Functions

The this keyword in JavaScript operates differently depending on the type of function. Regular functions determine this at call time based on the invocation context, whereas arrow functions lexically bind this from the surrounding scope.

How this Works in Regular Functions

For a standard function, this points to the object that calls the function. Consider the following:

function showThis() {
  console.log(this.label);
}

var label = 'global';
showThis(); // 'global'  (window.showThis())

The call is equivalent to window.showThis(), so this refers to the global object. Even if a local variable with the same name exists, this.label still resolves to the global one.

When a function is invoked as an object method, this becomes that object:

const person = {
  label: 'Alice',
  greet: function() {
    console.log(this.label);
  }
};
person.greet(); // 'Alice'

A commmon pitfall occurs when a function is returned and called separately:

var label = 'global';
const person = {
  label: 'Alice',
  greet: function() {
    return function() {
      console.log(this.label);
    };
  }
};
const sayHello = person.greet();
sayHello(); // 'global'  (standalone function call)

Common Invocation Patterns

  1. Simple function callthis refers to the global object (or undefined in strict mode).
function assignX() {
  this.x = 5;
}
assignX();
console.log(x); // 5 (global)
  1. Method callthis is the object owning the method.
function getX() {
  console.log(this.x);
}
const obj = { x: 20, showX: getX };
obj.showX(); // 20
  1. Constructor callthis is the newly created instance.
function User(name) {
  this.name = name;
}
const user = new User('Bob');
console.log(user.name); // 'Bob'
  1. Explicit binding.call(), .apply(), or .bind() can set this freely.
function identify() {
  console.log(this.id);
}
const a = { id: 'A' };
const b = { id: 'B' };

identify.call(a); // 'A'
identify.call(b); // 'B'

Arrow Functions: Lexical this

Arrow functions do not have their own this. Instead, they capture the this of the enclosing execution context at the time they are defined.

Consider an arrow function as an object field:

var label = 'global';
const obj = {
  label: 'local',
  log: () => {
    console.log(this.label);
  }
};
obj.log(); // 'global'

The arrow function log is defined inside the object literal. However, object literals do not create a new scope—the surrounding scope is the global scope. Therefore, this inside the arrow function is the global this.

To bind an arrow function to a specific object, wrap it inside a regular function:

var label = 'global';
const obj = {
  label: 'local',
  getLogger: function() {
    const logger = () => console.log(this.label);
    return logger;
  }
};

const logFn = obj.getLogger();
logFn(); // 'local'  (because getLogger was called on obj, so its this is obj)
logFn.call({ label: 'something else' }); // still 'local'

The arrow function inside getLogger captures this from its enclosing regular function. Since obj.getLogger() sets this to obj, the arrow function permanently retains that reference.

Key restrictions:

  • Arrow functions cannot be used as constructors; new throws an error.
  • They do not have their own arguments object. Use rest parameters instead.
  • Arrow functions lack yield and cannot serve as generator functions.

Tags: javascript this arrow functions regular functions scope

Posted on Sat, 29 Aug 2026 16:46:05 +0000 by freelancedeve