Exploring the WeakMap Feature in JS - Part 3

By Sammy at

In the previous parts of this series, we explored the basics and two common use cases of WeakMaps in JavaScript. In this part, we will look at a few more advanced use cases for WeakMaps: memoization and private properties.

Memoization

WeakMaps can be used for memoization, which is the process of caching the result of a function based on its input arguments. Memoization can help improve performance by avoiding the need to recompute the result for the same input arguments multiple times.

Here's an example of how a WeakMap can be used for memoization:

const cache = new WeakMap();

function memoize(fn) {
  return function(...args) {
    if (cache.has(args)) {
      return cache.get(args);
    }

    const result = fn(...args);
    cache.set(args, result);
    return result;
  };
}

In this example, the memoize function takes a function fn as input and returns a new function that memoizes the result of fn. The memoized function takes any number of arguments using the rest parameter syntax (...args). The memoized function checks if the cache already contains the result for the input arguments, and if so, returns it. If the result is not in the cache, the memoized function computes the result using fn(...args), stores the result in the cache, and returns it.

Using a WeakMap for memoization has several advantages. First, it avoids the need to recompute the result for the same input arguments multiple times. Second, the memoized values are automatically cleaned up by the garbage collector when the input arguments are no longer needed, which helps avoid memory leaks.

Private Properties

WeakMaps can also be used to create private properties for objects. Private properties are properties that are not visible outside the object, but can be accessed and modified by methods within the object.

Here's an example of how a WeakMap can be used to create private properties:

const privateData = new WeakMap();

class MyClass {
  constructor() {
    privateData.set(this, { value: 42 });
  }

  getPrivateValue() {
    return privateData.get(this).value;
  }

  setPrivateValue(newValue) {
    privateData.get(this).value = newValue;
  }
}

In this example, privateData is a WeakMap that is used to store private data for instances of the MyClass class. The private data is an object with a single property value, which is set to 42 in the constructor. The getPrivateValue method returns the value of the private property, and the setPrivateValue method sets the value of the private property.

Using a WeakMap for private properties has several advantages. First, it avoids naming conflicts with other properties or libraries that may be using the same property names. Second, the private data is automatically cleaned up by the garbage collector when the object is no longer needed, which helps avoid memory leaks. Third, because the private data is not exposed outside the object, it helps enforce encapsulation and prevents external code from modifying the object's internal state directly.

Conclusion

In this series, we explored the WeakMap feature in JavaScript, including its basics, common use cases, and more advanced use cases. WeakMaps are a powerful tool that can help improve performance, avoid memory leaks, and enforce encapsulation. By understanding the