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.parse and JSON.stringify (round-trip behavior)
  • MDN — Object initializer (the JavaScript object-literal syntax, ECMA-262 §13.2.5)

Last reviewed June 2026.