Hacker News new | past | comments | ask | show | jobs | submit login
ECMAScript 5 Strict Mode, JSON, and More (ejohn.org)
45 points by functional-tree on May 22, 2009 | hide | past | favorite | 21 comments



One irritation I have with native JSON parsing, is that it seems to require quotes around keys. I don't understand why, and think it's a bad choice.

For example, in js code, eval, other JSON parsers etc, the following works fine as you'd expect:

{foo:"bar"}

However, using the JSON.parse function, it'll fail. The following works:

{"foo":"bar"}

If anyone can shed some light on this, I'd be interested. I'd rather not send tons of useless quotes if I don't have to.


Some JavaScript implementations can't handle keywords as property names.

e.g. in Safari:

var a = { new: 'Monkey' }

fails. Thus the required quotes in the JSON spec.


Good point. I'd still rather they were optional though like in js.


Then why are you using JSON? JSON is for best practices. Requiring quotes so that some interpreters don't get confused is exactly the type of thing JSON is for.


The js spec says that quotes around property names are optional. Obviously they're needed if the property name is a reserved word.

I don't think it's a good argument to include needless quotes in a data format just so some bad interpreters don't get confused. Fix the interpreter - or just don't use reserved words, or enclose those in quotes if you use them.

Everything adds up. Imagine you were sending a few billion JSON objects a day. Requiring quotes on every single property name is wasteful and unnecessary. It's redundant useless information.

A hack around would be to regexp a replace to add quotes, and then JSON.parse it, but then you may as well just continue using eval, or a parser that doesn't care if you omit quotes, which is a shame.

IMHO, JSON.parse should function exactly as eval does for de-serializing js objects.


Despite the name, JSON is not isomorphic to the definition of JSON object literals. It is by design a subset. This provides both future-proofing against later changes in ECMAScript (adding keywords), and simplifies the grammar for conforming parsers. Simpler grammars mean less opportunity for errors and non-conformant implementations.

"A hack around would be to regexp a replace to add quotes, and then JSON.parse it,"

That is an absolutely terrible, terrible, terrible idea. Do not do that, especially if you're shipping around a "few billion JSON objects a day"! Running regexps over things that require a grammar to fully understand is asking for disaster.

"IMHO, JSON.parse should function exactly as eval does for de-serializing js objects."

The entire purpose is to get away from "eval". How do you like '{"test": window.close()}" in your JSON?

JSON is a cross-language serialization format that was inspired heavily by the fact that Perl, Python, and Javascript had very similar object literals and underlying data structures. It is not simply Javascript in a fancy spec, and you're missing the point if you think it is or treat it like it is. If you're just moving JS around, then ship whatever you like down. Back in the days before anybody had heard of JSON, I used to do that; as long as you're in control of the JS it works fine. (It's useless for communication between different entities, though.)


Please explain why the data format needs quotes around keys.

And yes, I'm just sending data from server to client. I couldn't care less if it conforms to some spec or not. I want an efficient, useful data format.

>> The entire purpose is to get away from "eval". How do you like '{"test": window.close()}" in your JSON?

You're absolutely correct. but that is simple to protect against with a regexp, which is how the json parser at json.org works - regexp it, then eval().

My point is, that for my use case, the native JSON parser will mean an increase in bandwidth. Which is a pain - especially as there isn't a good reason for it.


He did explain why:

"This provides both future-proofing against later changes in ECMAScript (adding keywords), and simplifies the grammar for conforming parsers. Simpler grammars mean less opportunity for errors and non-conformant implementations."

If it didn't require quotes, currently valid JSON may not be valid in the future if a new keyword which was use as a JSON object key was used unquoted. And there's the added complexity of supporting both quoted and unquoted keys.


A data format should NOT be concerned with language keywords.


Unless the data format is written in a language...


And all of them can't handle non-word characters like ":"

   var a = { foo:bar : 'Monkey' }


Agreed that it's an annoyance. Since Python requires quotes, I've grown accustomed to using the quotes when needed, even though it looks less clean. According to the JSON spec (http://json.org/), the quotes are required -- so it makes sense that the official parser would require them I suppose.


What JSON parser supports non-string object keys? I've used several for various languages, and even written a few, and never encountered one that allowed such a drastic deviation from the spec. Remember that JSON is only vaguely related to JavaScript -- just because some feature is possible in JavaScript (non-string keys, Infinity, etc) doesn't mean it's valid JSON. The only valid JSON is that which matches the grammar in RFC 4627[1].

For what it's worth, the corner cases in JavaScript make non-string keys very difficult to reasonably parse. For example, if {foo:"bar"} should parse to {"foo":"bar"}, then what should {1:"bar"} or {::"bar"} parse to?

[1] http://www.ietf.org/rfc/rfc4627.txt


I don't care about the RFC TBH, I care about what I can use in a practical use-case to transfer data internally in an optimal way.

The json parser at json.org parses non quoted keys just fine, since it uses eval().

{1:"bar"} would obviously create a property "1", and {::"bar"} would obviously not be valid.


Nobody seems to notice this, but using quotes stops you from error of using {foo:"bar"}. In JavaScript, {foo:"bar"} is not an Object, it is a code block containing a labeled code block with the label, foo, in it with a string, "bar". This is what {foo:"bar"} really means in JavaScript:

    {
      foo: {
        "bar";
      };
    }
Labels cannot be strings, so quoting them will help you catch this error earlier.


I'm not sure if your particular example is correct, but you're right that there are certain ambiguous cases involving labels and object literals.

There was a really good talk recently that touched on this, but I can't remember who gave it or what it was called.


a={foo:"bar"} creates an object called a with foo as a key mapping to "bar".


That's not a good reason. It's simple to spot that and enclose it in brackets.


I don't feel like transcribing it, but Douglas Crockford addresses this here:

http://www.youtube.com/watch?v=hQVTIJBZook#t=1h0m29s


Because keys are strings, and strings are wrapped in quotes.


That's not a reason.

var a = {foo:"bar"} is valid js code. It can be parsed with eval(). It should be valid for JSON.parse() as well.




Consider applying for YC's Spring batch! Applications are open till Feb 11.

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: