JavaScript JSON versus JavaScript literals


Example

JSON stands for "JavaScript Object Notation", but it's not JavaScript. Think of it as just a data serialization format that happens to be directly usable as a JavaScript literal. However, it is not advisable to directly run (i.e. through eval()) JSON that is fetched from an external source. Functionally, JSON isn't very different from XML or YAML – some confusion can be avoided if JSON is just imagined as some serialization format that looks very much like JavaScript.

Even though the name implies just objects, and even though the majority of use cases through some kind of API always happen to be objects and arrays, JSON is not for just objects or arrays. The following primitive types are supported:

  • String (e.g. "Hello World!")
  • Number (e.g. 42)
  • Boolean (e.g. true)
  • The value null

undefined is not supported in the sense that an undefined property will be omitted from JSON upon serialization. Therefore, there is no way to deserialize JSON and end up with a property whose value is undefined.

The string "42" is valid JSON. JSON doesn't always have to have an outer envelope of "{...}" or "[...]".

While nome JSON is also valid JavaScript and some JavaScript is also valid JSON, there are some subtle differences between both languages and neither language is a subset of the other.

Take the following JSON string as an example:

{"color": "blue"}

This can be directly inserted into JavaScript. It will be syntactically valid and will yield the correct value:

const skin = {"color": "blue"};

However, we know that "color" is a valid identifier name and the quotes around the property name can be omitted:

const skin = {color: "blue"};

We also know that we can use single quotes instead of double quotes:

const skin = {'color': 'blue'};

But, if we were to take both of these literals and treat them as JSON, neither will be syntactically valid JSON:

{color: "blue"}
{'color': 'blue'}

JSON strictly requires all property names to be double quoted and string values to be double quoted as well.

It's common for JSON-newcomers to attempt to use code excerpts with JavaScript literals as JSON, and scratch their heads about the syntax errors they are getting from the JSON parser.

More confusion starts arising when incorrect terminology is applied in code or in conversation.

A common anti-pattern is to name variables that hold non-JSON values as "json":

fetch(url).then(function (response) {
  const json = JSON.parse(response.data); // Confusion ensues!

  // We're done with the notion of "JSON" at this point,
  // but the concept stuck with the variable name.
});

In the above example, response.data is a JSON string that is returned by some API. JSON stops at the HTTP response domain. The variable with the "json" misnomer holds just a JavaScript value (could be an object, an array, or even a simple number!)

A less confusing way to write the above is:

fetch(url).then(function (response) {
  const value = JSON.parse(response.data);

  // We're done with the notion of "JSON" at this point.
  // You don't talk about JSON after parsing JSON.
});

Developers also tend to throw the phrase "JSON object" around a lot. This also leads to confusion. Because as mentioned above, a JSON string doesn't have to hold an object as a value. "JSON string" is a better term. Just like "XML string" or "YAML string". You get a string, you parse it, and you end up with a value.