-2

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?

Lonnie Best
  • 9,936
  • 10
  • 57
  • 97

2 Answers2

3

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.

CertainPerformance
  • 356,069
  • 52
  • 309
  • 320
  • 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? – Lonnie Best Nov 30 '19 at 08:58
  • 1
    It's not official, and I doubt anything like it will ever be, but one option is https://www.npmjs.com/package/serialize-javascript - *We've found that sometimes we need to serialize JavaScript functions, regexps, dates, sets or maps*. – CertainPerformance Nov 30 '19 at 09: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 Nov 30 '19 at 09: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](https://i.stack.imgur.com/91VyK.png). There are number of was to do it. I just wish there was a standard way. – Lonnie Best Nov 30 '19 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 Nov 30 '19 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.

  • 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. – Lonnie Best Nov 30 '19 at 09: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. – Shawn LaFrance Nov 30 '19 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](https://i.stack.imgur.com/91VyK.png). It looks good when you console the ary (you see type: 'Map') but JSON.stringify strips off that array property. – Lonnie Best Nov 30 '19 at 12:40
  • I think that's because you don't have your last array element wrapped ``{type: "map"}`` – Shawn LaFrance Nov 30 '19 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. – Lonnie Best Dec 02 '19 at 16:12
  • True, but this is more of an issue with the `Map` object rather than `JSON`. It really boils down to *do I want my data to define its own structure/implementation or not?* – Shawn LaFrance Dec 02 '19 at 18:05