95

The JSON spec says that JSON is an object or an array. In the case of an object,

An object structure is represented as a pair of curly brackets surrounding zero or more name/value pairs (or members). A name is a string. ...

And later, the spec says that a string is surrounded in quotes.

Why?

Thus,

{"Property1":"Value1","Property2":18}

and not

{Property1:"Value1",Property2:18}

Question 1: why not allow the name in the name/value pairs to be unquoted identifiers?


Question 2: Is there a semantic difference between the two representations above, when evaluated in Javascript?

Community
  • 1
  • 1
Cheeso
  • 189,189
  • 101
  • 473
  • 713
  • What do you mean by "in JSON"? It makes "JSON" look like a programming language. – Bruno Reis Jan 14 '10 at 22:21
  • 1
    @Bruno: You could speak of XML the same way... and sadly, some out there may well be trying to use XML as a programming language... – Mike DeSimone Jan 14 '10 at 22:24
  • 2
    +1 ... it does seem like a peculiar contradiction.... "with quotes" makes it standard JSON, but won't work with `eval()` (i.e. javascript). – skaffman Jan 14 '10 at 22:24
  • 2
    @bruno, no. if you expand it, it becomes "in Javascript Object Notation" which is fine – Dave Archer Jan 14 '10 at 22:30
  • 2
    @skaffman — It will work when evaled in JavaScript. – Quentin Jan 14 '10 at 22:34
  • 1
    @Bruno - JSON is a data format. "In JSON" means - with data formatted according to the spec. – Cheeso Jan 14 '10 at 22:37
  • This question is a duplicate of https://stackoverflow.com/q/4201441/8910547, which also has a better answer than the ones here. – Inigo May 04 '20 at 19:44
  • The [JSON5 superset spec](https://stackoverflow.com/a/61599957/8910547) adheres to ES5 syntax and thus supports unquoted keys amongst other things. The library has compatible `parse` and `stringify` methods. – Inigo May 04 '20 at 19:44
  • Does this answer your question? [Is there any practical reason to use quoted strings for JSON keys?](https://stackoverflow.com/questions/4201441/is-there-any-practical-reason-to-use-quoted-strings-for-json-keys) – Inigo May 04 '20 at 19:44

7 Answers7

141

I leave a quote from a presentation that Douglas Crockford (the creator of the JSON standard) gave to Yahoo.

He talks about how he discovered JSON, and amongst other things why he decided to use quoted keys:

.... That was when we discovered the unquoted name problem. It turns out ECMA Script 3 has a whack reserved word policy. Reserved words must be quoted in the key position, which is really a nuisance. When I got around to formulizing this into a standard, I didn't want to have to put all of the reserved words in the standard, because it would look really stupid.

At the time, I was trying to convince people: yeah, you can write applications in JavaScript, it's actually going to work and it's a good language. I didn't want to say, then, at the same time: and look at this really stupid thing they did! So I decided, instead, let's just quote the keys.
That way, we don't have to tell anybody about how whack it is.

That's why, to this day, keys are quoted in JSON.

You can find the complete video and transcript here.

mplungjan
  • 169,008
  • 28
  • 173
  • 236
Christian C. Salvadó
  • 807,428
  • 183
  • 922
  • 838
  • Ummm... the *creator* of the JSON standard ?! I believe that's an overstatement. JSON is the JavaScript Object Notation and comes from the Javascript (ECMA) spec. – Sorin Mocanu Jan 15 '10 at 11:22
  • 46
    @Sorin: Don't confuse JSON with JavaScript Object literals. JSON is a language-agnostic data interchange format, proposed by Crockford on 2006(http://tools.ietf.org/html/rfc4627), its grammar differs from the JavaScript Object literals (http://bclary.com/2004/11/07/#a-11.1.5), basically by allowing only *string* keys and the values *MUST* be an *object*, *array*, *number*, *string*, or one of the following literal names: *false*, *null* *true*. Object literals in JavaScript can have keys as *Identifiers*, *String literals* or *Number literals*, and the value can be any type of *expression*... – Christian C. Salvadó Jan 15 '10 at 21:23
  • @CMS And the JavaScript of today allows shorthand identifiers inside object constructor expressions, e.g: `{ a }`, where property 'a' copies the value of a global or local variable 'a'. –  Oct 27 '16 at 21:43
  • @CMS And there's also computed keys: `{[key]: value}` –  Oct 30 '16 at 14:47
  • @ChristianC.Salvadó that old bclary link to ECMA-262 ultimately leads to a 404 now. Perhaps this is a suitable replacement link? https://262.ecma-international.org/13.0/#sec-object-type – User Sep 07 '22 at 17:12
57

Question 1: why not allow the name in the name/value pairs to be unquoted identifiers?

The design philosophy of JSON is "Keep it simple"

"Quote names with "" is a lot simpler than "You may quote names with " or ' but you don't have to, unless they contain certain characters (or combinations of characters that would make it a keyword) and ' or " may need to be quoted depending on what delimiter you selected".

Question 2: Is there a semantic difference between the two representations above, when evaluated in Javascript?

No. In JavaScript they are identical.

Quentin
  • 914,110
  • 126
  • 1,211
  • 1,335
  • 4
    No it's not correct. CMS has the correct answer. This answer is just a nice side-effect of the real reason. Aside from being simpler to explain, it's also simpler to write a parser, since you can reuse the parse rules for strings on identifiers. – Breton Jan 14 '10 at 23:14
  • and aside from that, there's a slight semantic difference in that if an identifier happens to be a reserved word, it is interpreted as that word rather than as an identifier. – Breton Jan 14 '10 at 23:26
  • @nhnghia — Question 2 is about evaluating the source code **as JavaScript**, not JSON. `JSON.parse` is a JSON parser implemented in JavaScript, it isn't a JavaScript parser. – Quentin Jun 04 '19 at 09:58
0

Both : and whitespace are permitted in identifiers. Without the quotes, this would cause ambiguity when trying to determine what exactly constitutes the identifier.

Anon.
  • 58,739
  • 8
  • 81
  • 86
0

In javascript objects can be used like a hash/hashtable with key pairs.

However if your key has characters that javascript could not tokenize as a name, it would fail when trying it access like a property on an object rather than a key.

var test  = {};
test["key"] = 1;
test["#my-div"] = "<div> stuff </div>";

// test = { "key": 1, "#my-div": "<div> stuff </div>" };

console.log(test.key);           // should be 1
console.log(test["key"]);        // should be 1
console.log(test["#my-div"]);    // should be "<div> stuff </div>";
console.log(test.#my-div);       // would not work.

identifiers can sometimes have characters that can not be evaluated as a token/identifier in javascript, thus its best to put all identifiers in strings for consistency.

-3

I think the right answer to Cheeso's question is that the implementation surpassed the documentation. It no longer requires a string as the key, but rather something else, which can either be a string (ie quoted) or (probably) anything that can be used as a variable name, which I will guess means start with a letter, _, or $, and include only letters, numbers, and the $ and _.

I wanted to simplify the rest for the next person who visits this question with the same idea I did. Here's the meat:

Variable names are not interpolated in JSON when used as an object key (Thanks Friedo!)

Breton, using "identifier" instead of "key", wrote that "if an identifier happens to be a reserved word, it is interpreted as that word rather than as an identifier." This may be true, but I tried it without any trouble:

var a = {do:1,long:2,super:3,abstract:4,var:5,break:6,boolean:7};
a.break

=> 6

About using quotes, Quentin wrote "...but you don't have to, unless [the key] contains certain characters (or combinations of characters that would make it a keyword)"

I found the former part (certain characters) is true, using the @ sign (in fact, I think $ and _ are the only characters that don't cause the error):

var a = {a@b:1};

=> Syntax error

var a = {"a@b":1};
a['a@b']

=> 1

but the parenthetical about keywords, as I showed above, isn't true.

What I wanted works because the text between the opening { and the colon, or between the comma and the colon for subsequent properties is used as an unquoted string to make an object key, or, as Friedo put it, a variable name there doesn't get interpolated:

var uid = getUID();
var token = getToken();            // Returns ABC123
var data = {uid:uid,token:token};
data.token

=> ABC123

Dave Scotese
  • 498
  • 5
  • 17
-3

If json describes objects, then in practise you get the following

var foo = {};

var bar = 1;

foo["bar"] = "hello";
foo[bar] = "goodbye";

so then,

foo.bar == "hello";
foo[1] == "goodbye" // in setting it used the value of var bar

so even if your examples do produce the same result, their equivalents in "raw code" wouldn't. Maybe that's why?? dunno, just an idea.

Dave Archer
  • 3,022
  • 20
  • 23
  • 3
    @David, variable names are not interpolated in JS when used as an object key. `{ bar: 'goodbye' }` will not set the key name to the value of `bar`, it will just be `bar`. The others are right about the reason why the spec requires quotes: it's to avoid keyword and special-character conflicts. – friedo Jan 14 '10 at 23:07
-3

It may reduce data size if quotes on name are only allowed when necessary

shashank joshi
  • 140
  • 1
  • 4