Explain Codes LogoExplain Codes Logo

How do you JSON.stringify an ES6 Map?

javascript
json-stringify
map
replacer-function
Nikita BarsukovbyNikita BarsukovยทFeb 14, 2025
โšกTLDR

To convert an ES6 Map into a JSON string, transform it to an array first:

const mapToJson = JSON.stringify(Array.from(map)); // Map makes array, array makes string ๐Ÿฆ„๐Ÿ’ซ

Reviving a Map from this JSON string, is as simple as parsing the JSON and feeding it to the Map constructor:

const mapFromJson = new Map(JSON.parse(mapToJson)); // Rise, my child! ๐ŸงŸโ€โ™‚๏ธ๐Ÿ’ฅ

The process keeps the key-value pairings intact.

Deep dive: JSON Handling with replacer and reviver

For neater and more consistent result, we could use a replacer function alongside JSON.stringify. This function hunts down instances of Map and transforms them into a format that's easy to serialize.

function replacer(key, value) { if (value instanceof Map) { // Found one! ๐Ÿ•ต๏ธโ€โ™€๏ธ Map spotted. return { dataType: 'Map', value: Array.from(value.entries()), // array of [key, value] pairs }; } return value; // Else, business as usual. } const mapToJson = JSON.stringify(map, replacer); // Map goes in, JSON comes out ๐Ÿค“

To revive the Map from this JSON, we un-serialize it using a reviver function in JSON.parse.

function reviver(key, value) { if (typeof value === 'object' && value !== null && value.dataType === 'Map') { // Dangerous situation! ๐Ÿฒ Fire-breathing Map on sight. return new Map(value.value); // Cool it down with a new Map ๐Ÿ”ฅ๐Ÿ’ฆ๐Ÿ” } return value; // Else, proceed without panicking. } const mapFromJson = JSON.parse(mapToJson, reviver); // JSON goes in, Map comes out ๐Ÿคฏ

The custom handling takes care of nested structures, data types and preserves the data integrity.

Understand the quirks of serialization

String type coercion

JSON accepts strings as keys only. During serialization, all Map keys are converted (or coerced) into strings. Alien invasion ๐Ÿ‘ฝ๐Ÿš€! All non-string keys, beware.

Object as a Map substitute

Sometimes, a simple plain object could serve the purpose of a Map โ€” think narrow alleys instead of wide roads. This would bring the bonus of better performance and browser compatibility.

Insertion order matters

Place the bread on the counter before the butter, right? Similarly, ES6 Maps maintain order of insertion. While converting to other structures, remember to preserve this order.

Complex structures

When your Map is not a solo artist but part of a jazzy ensemble with Arrays, and Objects, it's important to build replacer and reviver functions that could handle this deep nesting without a breakdown.

// Assuming 'complexStructure' is a deeply nested structure with Maps, Arrays, Objects const complexToJson = JSON.stringify(complexStructure, replacer); // Structured chaos goes in, JSON comes out ๐ŸŽถ๐ŸŽต const complexFromJson = JSON.parse(complexToJson, reviver); // JSON goes in, jam session comes out ๐ŸŽบ๐ŸŽท๐Ÿฅ

The performance conductor ensures the band stays in rhythm.

Performance and alternatives

Beware of performance impacts while using Array.from() or spread operator [...map] in performance-critical applications. Running benchmarks could be useful to choose the right tool for your use case!

Serialization do's and don'ts

Remember, custom serialization could potentially introduce incompatibilities if you're dealing with systems expecting plain old JSON.

Additional Node.js tips

In case you're in the wonderful world of Node.js, utilities like util.inspect can help you achieve better control over object serialization.