-1

Are there any formal proposals, in progress, that address a backwards-compatible evolution to JSON's current treatment of Map objects?

For example, let say you want to convert a Map to JSON and then write it to file:

let map = new Map();
map.set(1, "A");
map.set(2, "B");
map.set(3, "C");

// Convert map to an "array of 2-element arrays":
let arrayFromMap = [... map];

let json = JSON.stringify(arrayFromMap);
writeJSONtoFile(json,"path/to/jsonFile.json");

So now we have a JSON file sitting on the disk. The issue is that, the code that ultimately reads this file has no knowledge that it contains a Map object unless we give that code-file that awareness. There is nothing inherent in JSON to explicitly indicate Map instead of a "array of 2-element arrays". For example, code not having this awareness might do this:

let json = readJSONfromFile("path/to/jsonFile.json");
let parsedJSON = JSON.parse(json);
console.log(parsedJSON); // outputs an "array of 2-element arrays"

However, if the the code writer gives the code awareness (that the original type was a Map) the file can be converted back to a Map:

let json = readJSONfromFile("path/to/jsonFile.json");
let map = new Map(JSON.parse(json));

This same awareness isn't necessary for these built-ins: Objects and Arrays.

In the example above, this "awareness" requirement isn't too burdensome. However, imagine a large hierarchy that contains both Maps and "arrays of 2-element arrays" that are not intended to be Maps. This "awareness burden" has now extended to each nested Map within the hierarchy.

Are there any formal proposals, in progress, that address a backwards-compatible evolution to JSON's current treatment of Map objects?

2 Answers 2

4

No, because JSON notation, while it originated with Javascript, is widely used in a very large number of languages, but a Javascript Map only has meaning within the context of Javascript.

Any sort of change to JSON notation to allow for the serialization and deserialization of objects that only have meaning in Javascript would make that JSON format incompatible with most other languages.

This isn't to say that a custom parser based on JSON couldn't be written to properly serialize and deserialize Maps, but such a thing would only be based on JSON, rather than being an addition to the JSON standard.

5
  • That makes sense. I wonder if ECMAscript will ever natively provide such a function (based on JSON without adding to JSON itself). Do you know of any proposals like that? Commented Nov 30, 2019 at 8:58
  • 1
    It's not official, and I doubt anything like it will ever be, but one option is npmjs.com/package/serialize-javascript - We've found that sometimes we need to serialize JavaScript functions, regexps, dates, sets or maps. Commented Nov 30, 2019 at 9:00
  • 1
    There's absolutely nothing stopping a JSON2 standard some day from adding other collection types besides an object and an array. It would probably have to be JSON2 in order to allow regular JSON to keep its wide compatibility it has now, but there's certainly no reason that there couldn't be a future standards effort around adding things like Sets and Maps which are trivial to express the data in JSON, but just need an indicator that they should be parsed into the appropriate collection type rather than an Array.
    – jfriend00
    Commented Nov 30, 2019 at 9:18
  • @jfriend00 You understand the essence what's missing (an explicit indicator to "parse as Map"). I tried the hacky idea of adding a property to the array (as an indicator), but JSON.stringify stripped it off. There are number of was to do it. I just wish there was a standard way. Commented Nov 30, 2019 at 12:55
  • 1
    @LonnieBest - Yeah, that's because JSON.stringify() doesn't grab properties of the array, only array elements. And, in the JSON spec, there's no way to express array properties that aren't items of the array. JSON would just need a way to specify a collection type and then a standard canonical way to express the data for each collection type. Right now it uses {} to specify an object and [] to specify an array (each a type of collection). It's very doable as a version 2 derivative if there was enough call for it.
    – jfriend00
    Commented Nov 30, 2019 at 15:59
1

Like CertainPerformance's answer, it's important that JSON remain as abstract as possible for the sake of portability and compatibility.

Wanted to add that keeping the integrity of the Map objects inside of a JSON object is really simple anyway without having to add a new specification; like adding a flag per Map during serialization.

6
  • When you say flag per Map, do you mean add a "flag" property to the "array of arrays" to indicate it is a Map? I know you can add properties to arrays, but wasn't sure if JSON also allowed that. Commented Nov 30, 2019 at 9:11
  • 1
    Since a map in JSON is represented by an array of keys/pairs, you could also just determine that it is a map during the parsing stage, too. Though I think it'd be better to have one of the elements of the array contain a single, non-key/pair value with a tag indicating that it's to be loaded differently. i.e ["isMap", ["a", "stuff"], ["key2", "more"]]. Map may just change in the future to better support deeply nested Map instances. Commented Nov 30, 2019 at 10:31
  • 1
    My code that parses the JSON needs an explicit indication, from within the JSON, that the array should be parsed as a Map. I tried what I thought you meant initially (actually adding a property to the array). See here. It looks good when you console the ary (you see type: 'Map') but JSON.stringify strips off that array property. Commented Nov 30, 2019 at 12:40
  • I think that's because you don't have your last array element wrapped {type: "map"} Commented Nov 30, 2019 at 13:22
  • No doubt, but that's what I was trying to test (adding a property to the array). This whole circumstance might be an example where XML would shine over JSON. XML allows you to store metadata in attributes instead of having to store that data within the content itself. Commented Dec 2, 2019 at 16:12

Not the answer you're looking for? Browse other questions tagged or ask your own question.