JavaScript Recursive Map Object: Transform Nested Values

Learn how to recursively map over a JavaScript object, transform nested values, preserve arrays, and create a new object without mutating input data.

Published

Updated

Read time 3 min read

Reviewed byDeepak Prasad

JavaScript Recursive Map Object: Transform Nested Values

Mapping over an object in JavaScript means creating a transformed version of its values. A normal Array.map() works only for arrays, so nested objects need a custom recursive function that checks whether each value is an array, object, or primitive value.

This pattern is useful when normalizing API responses, trimming strings, masking sensitive values, converting data types, or updating deeply nested configuration objects without mutating the original object.

Environment: Node.js v20.18.2. After each runnable snippet, the following paragraph states the expected console output (order and values).


Method 1: Recursively Map Every Primitive Value

This function keeps arrays as arrays, keeps objects as objects, and applies a callback only to primitive values.

javascript
function mapObject(value, fn) {
  if (Array.isArray(value)) {
    return value.map((item) => mapObject(item, fn));
  }

  if (value && typeof value === "object") {
    return Object.fromEntries(
      Object.entries(value).map(([key, child]) => [key, mapObject(child, fn)])
    );
  }

  return fn(value);
}

const data = { name: "ana", meta: { active: true }, scores: [1, 2] };
const result = mapObject(data, (value) =>
  typeof value === "string" ? value.toUpperCase() : value
);

console.log("recursive-map:", JSON.stringify(result));
Output

You should see one line logging recursive-map: {"name":"ANA","meta":{"active":true},"scores":[1,2]}.

The original structure is preserved while string values are transformed.


Method 2: Map Only Object Properties

If you only need shallow object mapping, use Object.entries() and Object.fromEntries().

javascript
const user = { first: "Ana", last: "Dev" };
const upper = Object.fromEntries(
  Object.entries(user).map(([key, value]) => [key, value.toUpperCase()])
);

console.log(upper);
Output

You should see one line logging { first: 'ANA', last: 'DEV' }.

Use the recursive version only when the object can contain nested objects or arrays.


Method 3: Preserve the Original Object

The recursive map function above returns a new object. It does not mutate the input object.

javascript
const original = { user: { name: "ana" } };
const mapped = mapObject(original, (value) =>
  typeof value === "string" ? value.toUpperCase() : value
);

console.log(original.user.name);
console.log(mapped.user.name);
Output

You should see 2 lines, in order: ana, ANA.

This makes the function safer for React state, Redux-style data, and other code where mutation can cause hard-to-find bugs.


Method 4: Handle null, Arrays, and Dates Carefully

In JavaScript, typeof null is "object", so always check value && typeof value === "object". Arrays also need their own branch because Object.entries() would convert array indexes into object keys.

If your data contains Date, Map, Set, or class instances, decide whether to preserve them, clone them, or transform them. A generic recursive object mapper should not blindly treat every object-like value as a plain object.


Common Questions About Mapping Objects in JavaScript

Can I use map() directly on an object?

No. map() is an array method. For objects, use Object.entries(), transform the entries, and rebuild the object with Object.fromEntries().

How do I map over nested objects?

Use recursion. Check arrays first, then plain objects, then apply the transform callback to primitive values.

Does recursive object mapping mutate the original object?

It depends on the implementation. The examples in this article return new objects and arrays, so the original input is preserved.


Summary

To recursively map an object in JavaScript, check whether each value is an array, object, or primitive value. Recursively map arrays and nested objects, then apply your transform function to the final values. This gives you a clean way to normalize or update deeply nested object data without mutating the original structure.


Official Documentation

Olorunfemi Akinlua

Boasting over five years of experience in JavaScript, specializing in technical content writing and UX design. With a keen focus on programming languages, he crafts compelling content and designs …