Is '""' a valid JSON string? - javascript

I am confused. To quote json.org
JSON is built on two structures:
A collection of name/value pairs. In various languages, this is
realized as an object, record, struct, dictionary, hash table, keyed
list, or associative array.
An ordered list of values. In most
languages, this is realized as an array, vector, list, or sequence.
So, I don't think '""' should be a valid JSON string as its neither a list values(i.e. does not start with '[' and ends with ']') but JSON.parse doesn't give exception and returns empty string.
Is it a valid JSON string.

No, '' is not valid JSON. JSON.parse('') does throw an error – just look in your browser console.
Next time you have an "is this valid JSON?" question, just run it through a JSON validator. That's why they exist.

So, I don't think "" should be a valid JSON string
It is a valid JSON string (which is a data type that may appear in a JSON text).
as its neither a list values(i.e. does not start with '[' and ends with ']')
A JSON text (i.e. a complete JSON document) must (at the outermost level) be…
(Here I cut the original answer because the specification has been revised).
A JSON text is a serialized value.
(quoting the JSON specification
So "" is a valid JSON text. This wasn’t the case when the original version of this answer was written. Some JSON parsers may break when the outer most value is not an object or array.
The original answer (which is now incorrect resumes here):
…either an object or an array. A string is not a valid JSON text.
The formal specification says:
A JSON text is a serialized object or array.
But back to quoting the question here:
but JSON.parse doesn't give exception and returns empty string.
The JSON parser you are using is being overly-liberal. Don't assume that all JSON parsers will be.
For example, if I run perl -MJSON -E'say decode_json(q{""})' I get:
JSON text must be an object or array (but found number, string, true, false or null, use allow_nonref to allow this) at -e line 1.

Following the newest JSON RFC 7159, "" is in fact valid JSON. But in some earlier standards it wasn't.
Quote:
A JSON text is a sequence of tokens. The set of tokens includes six structural characters, strings, numbers, and three literal names.
A JSON text is a serialized value. Note that certain previous specifications of JSON constrained a JSON text to be an object or an array.
Implementations that generate only objects or arrays where a JSON text is called for will be interoperable in the sense that all implementations will accept these as conforming JSON texts.

2023 Update
The other answers on this question are outdated and contain some incorrect information. The most recent JSON specification is RFC 8259, which obsoletes the previous RFCs referenced here. It says:
Note that certain previous specifications of JSON constrained a JSON text to be an object or an array.
A string by itself is therefore valid as an entire JSON text. It doesn't need to be contained within an outer object construct. The examples section of the RFC shows this:
Here are three small JSON texts containing only values:
"Hello world!"
42
true
The content of the string of course is irrelevant, so an empty string by itself is acceptable.
Note: JSON requires that strings be quoted with " so single quotes are still not valid:
"" // Valid
'' // Invalid

Related

safe JSON parsing. How JSON parse can parse UTF characters?

Hello I am wondering why this line doesn't work:
JSON.parse({"a":"\u00A9"})
I tried to serach in MDN website but I didn't find anything referring to in json.parse
Unicode escaping is syntactically legal in js according to this: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Lexical_grammar#String_literals
What is the problem and how can I safely parse text with JSON.parse
{"a":"\u00A9"} is a JavaScript object literal.
JSON.parse expects to be passed a string so it is implicitly converted to a string ("[object Object]").
The [ is fine, because a JSON text can start with an array.
The o is then an error because it isn't allowed there.
A literal copyright symbol (remember that \u00A9 inside a JavaScript string literal will be consumed by the JS parser before it gets to the JSON parser) or the unicode escape sequence would be fine.
console.log(JSON.parse('{"a":"\u00A9"}'));
console.log(JSON.parse('{"a":"\\u00A9"}'));
Note that creating a string literal in JS source code that contains JSON and then parsing it is a terrible idea. You have to deal with nested levels of escaping, and it is inefficient.
If you have an object: use the object.
var data = {"a":"\u00A9"};
console.log(data.a);

Why is JSON.parse so picky with quotes?

Basically, I am trying to create an object like this by providing a string to JSON.parse():
a = {x:1}
// -> Object {x: 1}
Intuitively I tried:
a = JSON.parse('{x:1}')
// -> Uncaught SyntaxError: Unexpected token x
After some fiddling I figured out:
a = JSON.parse('{"x":1}')
// -> Object {x: 1}
But then I accidentally changed the syntax and bonus confusion kicked in:
a = JSON.parse("{'x':1}")
//-> Uncaught SyntaxError: Unexpected token '
So now I am looking for an explanation why
one must to quote the property name
the implementation accepts single quotes, but fails on double quotes
The main reason for confusion seems to be the difference between JSON and JavaScript objects.
JSON (JavaScript Object Notation) is a data format meant to allow data exchange in a simple format. That is the reason why there is one valid syntax only. It makes parsing much easier. You can find more information on the JSON website.
Some notes about JSON:
Keys must be quoted with "
Values might be strings, numbers, objects, arrays, booleans or "null"
String values must be quoted with "
JavaScript objects on the other hand are related to JSON (obviously), but not identical. Valid JSON is also a valid JavaScript object. The other way around, however, is not.
For example:
keys and values can be quoted with " or '
keys do not always have to be quoted
values might be functions or JavaScript objects
As pointed out in the comments, because that's what the JSON spec specifies. The reason AFAIK is that JSON is meant to be a data interchange format (language agnostic). Many languages, even those with hash literals, do not allow unquoted strings as hash table keys.

JSON Attribute Best Practice

Usually, what I see is {"attribute":241241}
but writting this does exactly the same thing : {attribute:241241}.
Is {attribute:241241} considered bad practice and should be avoided or not?
{attribute:241241} does not validate using JSONLint, so yes, it is bad practice and should be avoided.
Further, if you look at the JSON spec at json.org, you will find that for objects the first value is always a string (indicated by double quotes).
You are confusing JSON with Object literal syntax, in Javascript doing
var o = {
"attribute":241241
};
is not JSON, but object literal. And yes, the quotes are useless there.
The JSON specification requires that keys be quoted, so the second form isn't valid JSON.
As Snakes and Coffee noted, it is a valid Javascript object literal (on which JSON is based), and some JSON parsers will accept it anyway. So it may work in some cases, but sooner or later you'll run into a perfectly functional JSON parser that rejects your non-quoted keys because they aren't valid per the spec.
As per the specification here, the names in name/value pairs must be of type string.
An object is an unordered collection of zero or more name/value pairs,
where a name is a string and a value is a string, number, boolean,
null, object, or array.

Why json string from obj.getAttribute doesn't want to parse?

var jsn=getAttr(ref,"json-data").toString();
console.log(jsn); //{test: true,stringtest:"hallo"}. it's OK.
JSON.parse(jsn); //Uncaught SyntaxError: Unexpected token s, line: line with JSON.parse;
I think JSON.parse does something not right with this data.. I tried to remove stringtest:"hallo" - no result... PS: also I think that I do something wrong then I have asked this question
At the first time I tried JSON.parse("{"+jsn+"}");.
Your JSON is not properly formatted, as your object keys must be surrounded by quotation marks. The following will work:
var jsn = '{"test": true, "stringtest": "hallo"}';
JSON.parse(jsn);
Edit: The RFC4627, which specifies JSON format, states:
2.2. Objects
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. A single colon comes after each name, separating the name
from the value. A single comma separates a value from a following
name. The names within an object SHOULD be unique.
object = begin-object [ member *( value-separator member ) ]
end-object
member = string name-separator value
As you can see, JSON objects are composed of name/value pairs, where a name is a string. Again, the RFC says:
The representation of strings is similar to conventions used in the C
family of programming languages. A string begins and ends with
quotation marks. All Unicode characters may be placed within the
quotation marks except for the characters that must be escaped:
quotation mark, reverse solidus, and the control characters (U+0000
through U+001F).
string = quotation-mark *char quotation-mark
quotation-mark = %x22 ; "
So, according to the RFC, keys must be surrounded by double quotes, not single one. Still, I guess some parsers may be more tolerant and accept both of them, but I'd stick to the standard.

Accessing Json fields with weird characters

i have a json string im converting to object with a simple eval(string);
heres the sample of the json string:
var json = #'
"{ description" : { "#cdata-section" : "<some html here>" } }
';
var item = eval('('+json+')');
I am trying to access it like so
item.description.#cdata-section
my problem is that javascript does not like the # in the field name.. is there a way to access it?
item.description['#cdata-section']
Remember that all Javascript objects are just hash tables underneath, so you can always access elements with subscript notation.
Whenever an element name would cause a problem with the dot notation (such as using a variable element name, or one with weird characters, etc.) just use a string instead.
var cdata = item.description["#cdata-section"];
While the official spec for JSON specifies simply for chars to be provided as a field identifier, when you parse your JSON into a Javascript object, you now fall under the restrictions of a Javascript identifier.
In the Javascript spec, an identifier can start with either a letter, underscore or $. Subsequent chars may be any letter, digit, underscore or $.
So basically, the # is valid under the JSON spec but not under Javascript.

Categories