Lodash forEach Execution Context in Class Methods

When using Lodash’s _.forEach within a JavaScript class method, understanding the execution context (this) is essential for properly accessing class properties and methods. In modern JavaScript (ES6+), classes run in strict mode by default, which alters how callbacks resolve their scope. This article explains how Lodash executes iteratee callbacks, why execution context can be lost inside class methods, and how to reliably preserve the class instance context.

Execution Context in ES6 Class Bodies

All code inside an ES6 class body automatically executes in strict mode ("use strict"). In strict mode, if a standard function is invoked without an explicit context, its this value remains undefined rather than defaulting to the global window or global object.

When invoking _.forEach, Lodash receives an iteratee callback and executes it internally as a plain function call:

iteratee(value, index, collection);

Because Lodash does not invoke this callback as a method of the class or apply an internal context binding by default, any standard function declaration or function expression passed to _.forEach will lose access to the calling class instance. Inside that callback, this will evaluate to undefined.

Lodash v3 vs. Lodash v4 Context Handling

In older versions of Lodash (v3 and earlier), collection methods accepted an optional third parameter: thisArg. This parameter allowed developers to pass the desired execution context directly to _.forEach:

// Supported in Lodash v3, REMOVED in Lodash v4
_.forEach(this.items, function(item) {
  this.processItem(item);
}, this);

Starting with Lodash v4, the library removed the thisArg parameter across its API to reduce library size and align with modern JavaScript features. Consequently, modern Lodash delegates context management entirely to the developer.

Preserving Class Context in Lodash Iterations

To maintain access to the class instance inside a _.forEach callback, developers must explicitly bind the context. There are three standard approaches:

Arrow functions do not define their own this binding; instead, they capture the lexical execution context of the enclosing scope. When used inside a class method, an arrow function automatically retains the class instance as this:

class TaskQueue {
  constructor() {
    this.tasks = ['task1', 'task2'];
  }

  processTasks() {
    _.forEach(this.tasks, (task) => {
      // 'this' correctly points to the TaskQueue instance
      this.logTask(task);
    });
  }

  logTask(task) {
    console.log(`Processing: ${task}`);
  }
}

2. Function.prototype.bind()

If using standard function syntax, you can bind the callback to the instance manually using native JavaScript:

processTasks() {
  _.forEach(this.tasks, function(task) {
    this.logTask(task);
  }.bind(this));
}

3. Lodash _.bind()

Alternatively, Lodash provides a utility method to achieve the same result:

processTasks() {
  _.forEach(this.tasks, _.bind(function(task) {
    this.logTask(task);
  }, this));
}

Summary

Lodash's _.forEach does not automatically manage or inject execution contexts when invoked inside class methods. Because modern Lodash omits the legacy thisArg parameter and class methods enforce strict mode, regular callback functions evaluate this as undefined. Using ES6 arrow functions or explicit binding mechanisms is required to access the class instance within the iteratee.