JSON vs JS Object Literal: The Key Differences
JSON looks like a JavaScript object literal, but it is a smaller data format with stricter syntax and no executable values.
The short version
A JavaScript object literal is source code. JSON is a data interchange format. The overlap is large enough to be confusing, but the rules are different: JSON keys and strings require double quotes, JSON has no comments, and JSON cannot represent functions, undefined, NaN, Infinity, Date objects, or regular expressions.
Stated tightly: every JSON document is a valid JavaScript expression, but most JavaScript object literals are not valid JSON.
Side-by-side comparison
| Feature | JavaScript object literal | JSON |
|---|---|---|
| Key quoting | optional (name: or "name":) |
required — keys must be double-quoted strings |
| String quotes | single, double, or backtick | double only |
| Trailing comma | allowed | forbidden |
Comments (// or /* */) |
allowed | forbidden |
undefined |
valid value | not representable |
NaN, Infinity |
valid numbers | not representable (serialize to null) |
| Functions / methods | valid | not representable |
Date, RegExp, Map, Set |
valid objects | not representable as themselves |
Hex / octal / numeric separators (0xff, 1_000) |
valid | forbidden |
| Spec | ECMA-262 §13.2.5 (Object Initializer) | RFC 8259 + ECMA-404 |
Valid JSON values
A JSON document can contain an object, array, string, number, boolean, or null. Strings must use double quotes; object keys must also be strings in double quotes. Numbers cannot include JavaScript-only forms such as hex notation, NaN, Infinity, or numeric separators.
- Valid JSON string:
"hello" - Valid JSON boolean:
true - Valid JSON null:
null - Valid JSON object key:
"name"
Valid JavaScript but invalid JSON
This object literal runs fine in a JavaScript program but JSON.parse rejects it on the first byte that breaks the spec:
{
name: 'Ada', // unquoted key + single-quoted string
active: true,
createdAt: new Date(), // constructor call — JSON has no Date type
onSave() { return true }, // method — JSON has no functions
tags: ['dev',], // trailing comma — RFC 8259 forbids it
// a comment // JSON has no comments
}
Each line is a different reason: an unquoted key, single quotes around a string, a constructor call, a method, a trailing comma, and a comment. All six are legal JavaScript object-literal syntax (per ECMA-262 §13.2.5) and all six are rejected by JSON.parse. For the same comparison through the single-quote lens specifically, see why JSON requires double quotes.
Valid JSON version
The same data, expressed as valid JSON:
{
"name": "Ada",
"active": true,
"createdAt": "2026-05-13T00:00:00.000Z",
"tags": ["dev"]
}
The Date became an ISO 8601 string, the trailing comma was removed, the unquoted key got double quotes, the single-quoted string also got double quotes, the method was dropped (it can't be carried in data), and the comment moved out of the document.
Round-Trip Pitfalls
JSON.stringify then JSON.parse is the standard way to deep-clone "plain data" in JavaScript, but the round trip is lossy for several JavaScript types:
| In | After JSON.parse(JSON.stringify(x)) |
|---|---|
Date |
string (ISO 8601), one-way — the prototype is lost |
undefined (as a value) |
key omitted entirely |
undefined (in an array) |
becomes null |
NaN, Infinity, -Infinity |
null |
Function |
dropped (key omitted) |
Map, Set, Symbol |
dropped or serialized as {} |
BigInt |
throws TypeError |
| Circular references | throws TypeError |
If your object survives a round trip with no changes, it's safe to send as JSON. If the round trip silently mutates it, your API payload is going to misbehave in ways that are hard to debug — and if you also need a static type for the cleaned data afterwards, generate TypeScript interfaces from the round-tripped JSON so the type system reflects what actually crosses the wire.
For the formal behavior of these conversions, see the MDN reference for JSON.parse and JSON.stringify.
Why APIs reject JavaScript-looking data
API servers generally parse request bodies with a JSON parser, not a JavaScript engine. That's a security and interoperability feature: every language can parse the same data without executing code, so a Python service (json.loads), a Go service (encoding/json), and a Rust service (serde_json) can all consume the same payload. JSON's grammar — defined in RFC 8259 and ECMA-404 — is deliberately small for exactly this reason.
If a request body includes comments, methods, undefined, or new Date(), the server cannot safely treat it as plain data. Permissive parsers exist (JSON5, for example), but the public web has standardized on strict RFC 8259 JSON precisely because every language can implement it the same way.
How to convert safely
The pragmatic recipe: replace executable or language-specific values with plain data.
- Dates → ISO 8601 strings (
new Date().toISOString()). The receiver re-parses them. - Missing values → either
null(still in the payload, value unknown) or omit the key (value not provided). These mean different things; pick deliberately. - Comments → move into developer docs or an OpenAPI / JSON Schema description field.
- Functions → represent as an explicit discriminator (
"action": "send_email") and resolve it on the receiving side. Map/Set→ serialize to arrays or objects; reconstruct on the other side.
If you're not sure whether a blob of data is valid JSON or something else, paste it into JSON Fix — it'll round-trip cleanly and surface the first byte that breaks the spec. For converting in the other direction, JSON to JavaScript object converter walks through the reverse path.
See also
This guide is one stop in a larger repair workflow that covers trailing commas, unquoted keys, single quotes, and stringified-object errors. Open the hub for the full sequence.
Sources
- RFC 8259 — the JSON Data Interchange Format (IETF, the canonical JSON grammar)
- ECMA-404 — the JSON Data Interchange Syntax (Ecma International, the parallel JSON spec)
- MDN —
JSON.parseandJSON.stringify(round-trip behavior) - MDN — Object initializer (the JavaScript object-literal syntax, ECMA-262 §13.2.5)
Last reviewed June 2026.
JSON repair guides
Topic hubs
- JSON Parse Errors: Read the Message, Jump to the Fix
- Fix Invalid JSON: From 'What's Wrong' to a Clean File
- JSON Formatter, Validator, Viewer: Pick the Right Tool
- Repair LLM JSON Output: Handling Almost-JSON from AI
- Privacy: JSON Tools That Don't Leave Your Browser
- JSON Interop: YAML, CSV, XML, JWT, Schema
Specific guides
- How to Decode Base64 Strings (and JWT Payloads)
- URL Encoding: Percent-Encode Query Parameters and Paths
- Convert YAML to JSON (and Avoid Indentation Errors)
- Convert JSON to CSV: Flatten an Array of Objects
- Convert JSON to XML: Root Elements, Attributes, and Arrays
- Escape JSON as a String Literal (and Decode Double-Encoded JSON)
- Fix Trailing Comma in JSON
- Fix Single Quotes in JSON
- Fix Unquoted Keys in JSON
- Repair LLM JSON Output
- Fix JSON Parse Error: Expected Property Name
- Validate JSON Before API Requests
- JSON Formatter vs JSON Repair
- Fix JSON Unexpected Token Errors
- JSON to JavaScript Object Converter