Adaptive Notation for JSON
# Andrea Giammarchi (7 years ago)
My 2 cents.
For classes with a reachable namespace from the window / global and serializable arguments, you could use an ad-hoc structure to define complex values:
// the converter
const toJSONStruct = value =>
Object.defineProperty(
{
"arguments": Symbol.iterator in value ?
[[...value]] :
[value.valueOf()]
},
"__proto__",
{
enumerable: true,
value: value.constructor.name
}
);
// the replacer (basic example)
const replacer = (key, value) => {
if (
typeof value === 'object' &&
value &&
!/^(?:Array|Object)$/.test(value.constructor.name)
) return toJSONStruct(value);
return value;
};
Here how you can produce some JSON
// example of a complex value
JSON.stringify(
{
property: new Uint8Array([10, 20, 30])
},
replacer,
' '
);
/*
{
"property": {
"arguments": [
[
10,
20,
30
]
],
"__proto__": "Uint8Array"
}
}
*/
A revirer example:
const reviver = (key, value) => {
if (
typeof value === 'object' &&
value !== null &&
value.hasOwnProperty('__proto__')
) {
const Class = value.__proto__
.split('.')
.reduce((O, K) => O[K], window);
return new Class(...value.arguments);
}
return value;
};
and a quick proof of the demo:
console.log(
JSON.parse(
`{
"property": {
"arguments": [
[
10,
20,
30
]
],
"__proto__": "Uint8Array"
}
}`,
reviver
)
);
Having this standardized, since it's very unlikely anyone would use
__proto__
key for a different reason, seems like an easier way to reason
about complex serialized values.
Having toJSON
and or toJSONConstructor
able to return such struct
instead of needing toJSONStruct
would be even better.
Best
Trying again...
It turned out that the Oracle/Java JSON API actually is I-JSON compatible by default through a method which I have coined "Adaptive Notation":
{ "BigDecimal.large": "1E+999", "BigDecimal.small": 1, "BigInteger.large": "240777489003222785532321", "BigInteger.small": 1, "Long.large": "9223372036854775807", "Long.small": 1 }
Personally I prefer schemes where you either use JSON Number or JSON String, rather than mixing these depending on the actual value.
However, the most important is finding a common solution.
WDYT?
Anders