How to Fix Error When Using the "this" Keyword in JavaScript Array Methods

2 min read

Consider a Java and TypeScript implementation of an Adder classes. The class takes a list of numbers and adds each number by x.

In Java, we can pass a method into a stream with the this keyword.

import java.util.Collection;
import java.util.stream.Collectors;

class Adder {
  private final int x;

  Adder(int x) {
    this.x = x;
  }

  private int add(int n) {
    return this.x + n;
  }

  public Collection<Integer> addAll(Collection<Integer> ns) {
    return ns
        .stream()
.map(this::add)
.collect(Collectors.toList()); } }

An analogous class in TypeScript looks like the this.

class Adder {
  private readonly x: number;

  constructor(x: number) {
    this.x = x;
  }

  private add(n: number) {
    return this.x + n;
  }

  addAll(ns: number[]) {
return ns.map(this.add);
} }

The Java implementation of addAll works. But if we run addAll in the JavaScript implementation, we get an error that this is undefined.

new Adder(2).addAll([1, 2, 3]);
// Uncaught TypeError: Cannot read property 'x' of undefined

Luckily, the fix is simple: Wrap your function in a high-order function.

class Adder {
  addAll(ns: number[]) {
return ns.map((n) => this.add(n));
} }

Now when we run our sample client, this is defined in the private helper method and we don’t get the error.

new Adder(2).addAll([1, 2, 3]);
// [3, 4, 5]