Skip to content

Filter Object

When to use

Use this when you need a new object containing only specific keys from an existing object. Common cases include input sanitization before assigning to a class instance, preventing prototype pollution by allowlisting known fields, and stripping extra keys before passing options to a third-party library that warns about unknown configuration properties.

The pattern

A filterObject(object, keys) function that returns a new object with only the specified keys. It is a lightweight equivalent of Lodash's _.pick().

Basic usage

javascript
const original = { a: 1, b: 2, c: 3 };
filterObject(original, ["a", "c"]);
// => { a: 1, c: 3 }

filterObject(original, []);
// => {}

filterObject(original, ["a", "z"]);
// => { a: 1 }  (missing keys are silently ignored)

Class constructor sanitization

The most common usage pairs filterObject with Object.assign to safely initialize instances:

javascript
class RecurringTask {
  constructor(input = {}) {
    const safe = filterObject(input, [
      "description",
      "type",
      "category",
      "account",
      "amount",
      "dueday",
      "recurrence",
      "link",
    ]);
    Object.assign(this, safe);
  }
}

This prevents callers from injecting properties like toString, constructor, or any field the class does not expect.

Stripping unexpected library options

Some libraries warn or break when they receive configuration keys they do not recognize. Filter before passing:

javascript
function createPool(config) {
  const connectionInfo = filterObject(config, [
    "socketPath",
    "user",
    "password",
    "database",
    "connectTimeout",
    "debug",
    "namedPlaceholders",
    "multipleStatements",
  ]);
  return mysql.createPool(connectionInfo);
}

Implementing filterObject()

The function converts the object to entries with Object.entries(), filters against the allowlist with Array.includes(), and reconstructs the result with Object.fromEntries().

javascript
export function filterObject(object, keys = []) {
  const allEntries = Object.entries(object);
  const allowed = allEntries.filter(
    ([key]) => keys.includes(key)
  );
  return Object.fromEntries(allowed);
}

Trade-offs

  • Pros: Zero dependencies, easy to understand, works with any plain object. Safer than destructuring because the allowlist is a data structure you can build dynamically.
  • Cons: keys.includes() is O(n) per entry. For objects with hundreds of keys and a large allowlist, convert keys to a Set first. For most configuration and input objects this is irrelevant.
  • Versus destructuring: Destructuring (const { a, c } = obj) works when the key set is static and known at write time. filterObject is better when the allowlist is defined as data (an array of strings) or when the result needs to stay as a single object for Object.assign or spread.