Every JSON document is already a valid JavaScript expression. You can paste
JSON into a const config = assignment and it runs. The interesting work
is the reverse: real JavaScript object literals are full of things JSON
forbids, and a converter that guesses what they meant loses data while
reporting success.
Using the JSON to JavaScript converter
Pick a direction and press Convert. Writing to JavaScript, an object key
that is a valid identifier is written bare, so "name" becomes name,
while a key like "display name" stays quoted because writing it bare
would change its spelling. An empty object or array stays on one line.
Numbers travel through the token stream rather than through JSON.parse,
so a twenty digit integer comes back with all twenty digits.
What the reader accepts
Reading JavaScript back into JSON, the tool understands the object literals
you would actually paste out of a config file: unquoted keys, single quoted
strings, // and /* */ comments, trailing commas, and an optional
const, let or var name at the front with a semicolon at the end.
A template literal without interpolation is accepted too, since it holds
plain text.
A number spelling JSON rejects is normalized to its exact JSON form:
const numbers = { a: .5, b: 5., c: 5.e3 }
{
"a": 0.5,
"b": 5,
"c": 5e3
}
What is refused, and why
Anything JSON cannot hold is refused by name rather than guessed at.
undefined, NaN and Infinity have no JSON number or value, so they are
refused. So are hex, octal and binary numbers, underscore digit separators
like 1_000, and a leading zero, all of which would change meaning if JSON
read them. A regular expression, a function, a bare word, and ${...}
template interpolation are refused as well, because those are code, not
data.
Two refusals deserve a closer look. A key that appears twice in one object
is refused, since JSON has no way to hold both values under one name. And a
__proto__ key whose value is an object or null is refused, because in a
JavaScript object literal that spelling does not create a property. It sets
the prototype of the new object, so converting it to JSON with an ordinary
__proto__ key would invent a property the original code never had.
Why undefined is not turned into null by default
JSON has no undefined, so a converter has to do something. Writing null
silently changes what the data meant: an undefined in a config object
usually means a field is not configured yet, which is not the same as a
null the code later checks for. The tool refuses by default, and the
Convert undefined to null option exists for when you genuinely want that
meaning.
Round tripping
Converting a document back to the other format is the real test of whether the quoting and refusal rules are right. An object literal with unquoted keys, single quotes and a trailing comma comes back as JSON with every key quoted and every digit intact, and converting that JSON forward again returns the same object. A wrong rule usually only shows up when you convert back and compare.