Stringify/Parse anything by extending JSON to ALL ES6 = ECMA-2015 data types
npm install json-es6json object extends JSON. The package is appropriately named because of the following
s = json.stringify(x) that is valid JavaScript
const y = eval('( + s + ')' produces a copy y of the original object x.
json.parse(s) that also produces a copy of the original object.
eval in favor of real hard-core letter by letter parsing, whence
json.parse() is already made to be faster, but it is not debugged.
npm install json-es6
const {json} = require('json-es6')
const s = json.stringify(x)
const y = eval('(' + s + ')') // y is a copy of x
const z = json.parse(s) // z is a copy of x
`
Example: Primitives and ES5 classes
`
const x =
{
a:undefined,
b:-Infinity,
c: -0,
d:12333333333333333333337777777777777777777777n,
e:true,
f:"cat",
g: new Boolean(true),
h: new Boolean(false),
i: new Number(7),
j: new String("cat"),
k: new Date(1234),
l: /abc/g,
}
json.stringify(x) is
{
"a":undefined,
"b":-Infinity,
"c":-0,
"d":12333333333333333333337777777777777777777777n,
"e":true,
"f":"cat",
"g":new Boolean(true),
"h":new Boolean(false),
"i":new Number(7),
"j":new String("cat"),
"k":new Date(1234),
"l":new RegExp('abc','g')
}
`
Example: Sets, Maps, and Typed Arrays
`
const x =
{
m: new Set(["cat", "dog", "hamster",
new Int16Array([-255, -256, -257])]),
n: new Map([[{a:1}, "cow"], ["horse", {b:2}]])
}
json.stringify(x) is
{
"m":new Set(
[
"cat",
"dog",
"hamster",
new Int16Array(
[
-255,
-256,
-257
])
]),
"n":new Map(
[
[
{
"a":1
},
"cow"
],
[
"horse",
{
"b":2
}
]
])
}
`
Example: Typed Arrays with Offsets
`
const x = new Int16Array(
new Uint16Array([-255,-256,-257,-258, -259, -230])
.buffer, 2,2)
json.stringify(x) is
new Int16Array(new Int16Array(
[
-255,
-256,
-257,
-258,
-259,
-230
]).buffer,2,2)
`
Example: ArrayBuffer
ArrayBuffers are written with Uint8Array encoding
`
const x = new Uint16Array([256, 257]).buffer
json.stringify(x) is
new Uint8Array(
[
0,
1,
1,
1
]).buffer
`
Example: DataView
DataViews are written with Uint8Array encoding.
`
const x = new DataView(new Uint16Array([256,257,258]).buffer)
json.stringfy(x) is
new DataView(new Uint8Array(
[
0,
1,
1,
1,
2,
1
]).buffer)
`
Example: DataView with Offset
`
const buffer = new Uint16Array([256, 257, 258, 259]).buffer
const x = new DataView(buffer, 2, 4)
json.stringfy(x) is
new DataView(new Uint8Array(
[
0,
1,
1,
1,
2,
1,
3,
1
]).buffer,2,4)
`
Example: WeakSets, WeakMaps, and Symbols
`
const x = {a:new WeakSet([...]), b:new WeakMap([...]), c: Symbol(...)}
json.stringify(x) is
{
"a":new WeakSet(),
"b":new WeakMap(),
"c":Symbol()
}
`
WeakSets and WeakMaps are written without any information about their internal state, because
there is no access to their internal state. When read, new WeakSets and WeakMaps are created,
which of course will have different internal states than their originals.
The discussion above for WeakSets and WeakMaps also holds for Symbols.
But here,if there is a Symbol somewhere in the object tree, a JSON copy will never be
deep-strict-equal because the target and source symbols will be different.
Example: Error and Error-Variant Classes
The stack property is not written, and so not read. Thus, if y = json.parse(json.stringify(x))
or equivalently if y = eval('(' + json.stringify(x) + ')' then y is a deep copy of x, except
that corresponding error objects will have different stacks.
`
const x = {a:new Error("error message"), b:new RangeError("range error message")}
json.stringify(x) is
{
"a":new Error("error message"),
"b":new RangeError("range error message")
}
`
Testing
See the test folder. Copies are made through the json process, and verified with
a wrapper around assert.deepStrictEqual().
Verifying JSON copies is best done with assert.deepStrictEqual() or deepStrictEqual()` from