Warum wird in JSON jeder Name zitiert?

91

Die JSON-Spezifikation besagt, dass JSON ein Objekt oder ein Array ist. Im Falle eines Objekts,

Eine Objektstruktur wird als ein Paar geschweifter Klammern dargestellt, die null oder mehr Name / Wert-Paare (oder Elemente) umgeben. Ein Name ist eine Zeichenfolge. ...

Und später heißt es in der Spezifikation, dass eine Zeichenfolge in Anführungszeichen gesetzt ist.

Warum?

So,

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

und nicht

{Property1:"Value1",Property2:18}

Frage 1 : Warum nicht zulassen, dass der Name in den Name / Wert-Paaren nicht zitierte Bezeichner sind?


Frage 2 : Gibt es einen semantischen Unterschied zwischen den beiden obigen Darstellungen, wenn sie in Javascript ausgewertet werden?

Cheeso
quelle
1
@Bruno: Sie könnten auf die gleiche Weise von XML sprechen ... und leider versuchen einige da draußen möglicherweise, XML als Programmiersprache zu verwenden ...
Mike DeSimone
2
+1 ... es scheint ein merkwürdiger Widerspruch zu sein ... "mit Anführungszeichen" macht es zum Standard-JSON, funktioniert aber nicht mit eval()(dh Javascript).
Skaffman
2
@ Bruno, nein. Wenn Sie es erweitern, wird es "in Javascript Object Notation", was in Ordnung ist
Dave Archer
2
@skaffman - Es funktioniert, wenn es in JavaScript ausgewertet wird.
Quentin
1
@Bruno - JSON ist ein Datenformat. "In JSON" bedeutet - mit Daten, die gemäß der Spezifikation formatiert sind.
Cheeso

Antworten:

57

Frage 1: Warum nicht zulassen, dass der Name in den Name / Wert-Paaren nicht zitierte Bezeichner sind?

Die Designphilosophie von JSON lautet "Keep it simple".

„Zitat - Name mit " ist viel einfacher , als „Sie Namen mit Zitat können "oder 'aber Sie haben nicht zu, es sei denn , sie bestimmte Zeichen (oder Kombinationen von Zeichen , die es ein Schlüsselwort machen würde) und 'oder "müssen quotiert werden je auf welchem ​​Trennzeichen Sie ausgewählt haben " .

Frage 2: Gibt es einen semantischen Unterschied zwischen den beiden obigen Darstellungen, wenn sie in Javascript ausgewertet werden?

Nein. In JavaScript sind sie identisch.

QUentin
quelle
3
Nein, es ist nicht richtig. CMS hat die richtige Antwort. Diese Antwort ist nur eine nette Nebenwirkung des wahren Grundes. Abgesehen davon, dass es einfacher zu erklären ist, ist es auch einfacher, einen Parser zu schreiben, da Sie die Analyseregeln für Zeichenfolgen auf Bezeichnern wiederverwenden können.
Breton
Abgesehen davon gibt es einen kleinen semantischen Unterschied darin, dass ein Bezeichner, wenn er zufällig ein reserviertes Wort ist, eher als dieses Wort als als Bezeichner interpretiert wird.
Breton
2
+1 auf die Antwort von CMS, das ist richtig. Doppelte Anführungszeichen sind keine Codekonvention, aber Sie möchten die reservierten Wörter als Schlüssel im Objekt vermeiden. Zum Beispiel: {property1: "abc", this: "def"} ist FALSCH (dies ist ein reserviertes Schlüsselwort)
Sorin Mocanu
Frage 2 : Ein kleiner Unterschied in Javascript bei Verwendung der JSON.parseFunktion: Funktioniert JSON.parse('{"a":1}') gut , warum JSON.parse('{a:1}')wird eine Ausnahme ausgelöst .
Nhnghia
@nhnghia - In Frage 2 geht es darum, den Quellcode als JavaScript und nicht als JSON auszuwerten . JSON.parseist ein in JavaScript implementierter JSON-Parser, kein JavaScript-Parser.
Quentin
134

Ich hinterlasse ein Zitat aus einer Präsentation, die Douglas Crockford (der Schöpfer des JSON-Standards) Yahoo gegeben hat.

Er spricht darüber, wie er JSON entdeckt hat und warum er sich unter anderem für die Verwendung von Anführungszeichen entschieden hat :

.... Da entdeckten wir das Problem des nicht zitierten Namens. Es stellt sich heraus, dass ECMA Script 3 eine Whack-Richtlinie für reservierte Wörter enthält. Reservierte Wörter müssen an der Schlüsselposition zitiert werden, was wirklich ein Ärgernis ist. Als ich dazu kam, dies in einen Standard zu formulieren, wollte ich nicht alle reservierten Wörter in den Standard einfügen müssen, weil es wirklich dumm aussehen würde.

Zu der Zeit habe ich versucht, die Leute zu überzeugen: Ja, Sie können Anwendungen in JavaScript schreiben, es wird tatsächlich funktionieren und es ist eine gute Sprache. Ich wollte also nicht gleichzeitig sagen: und sieh dir diese wirklich dumme Sache an, die sie getan haben! Also habe ich beschlossen, stattdessen nur die Schlüssel zu zitieren.
Auf diese Weise müssen wir niemandem erzählen, wie verrückt es ist.

Aus diesem Grund werden Schlüssel bis heute in JSON zitiert.

Das vollständige Video und Transkript finden Sie hier .

CMS
quelle
Ummm ... der Schöpfer des JSON-Standards ?! Ich glaube, das ist eine Übertreibung. JSON ist die JavaScript-Objektnotation und stammt aus der Javascript (ECMA) -Spezifikation.
Sorin Mocanu
42
@ Sorin: Verwechseln Sie JSON nicht mit JavaScript-Objektliteralen. JSON ist ein sprachunabhängiges Datenaustauschformat, das von Crockford 2006 vorgeschlagen wurde ( tools.ietf.org/html/rfc4627 ). Seine Grammatik unterscheidet sich von den JavaScript- Objektliteralen ( bclary.com/2004/11/07/#a-11.1) .5 ), im Allgemeinen , indem sie nur String Schlüssel und die Werte muss ein sein Objekt , Array , Anzahl , Zeichenkette , oder eine der folgenden literal Namen: falsch , null wahr . Objektliterale in JavaScript können Schlüssel als Bezeichner , Zeichenfolgenliterale oder habenZahlenliterale , und der Wert kann jede Art von Ausdruck sein ...
CMS
@CMS Und das heutige JavaScript erlaubt Kurzbezeichner in Objektkonstruktorausdrücken, z. B.: Wobei die { a }Eigenschaft 'a' den Wert einer globalen oder lokalen Variablen 'a' kopiert.
Hydroper
@CMS Und es gibt auch berechnete Schlüssel:{[key]: value}
Hydroper
0

Sowohl :als auch Leerzeichen sind in Bezeichnern zulässig. Ohne die Anführungszeichen würde dies zu Mehrdeutigkeiten führen, wenn versucht wird, festzustellen, was genau den Bezeichner ausmacht.

Anon.
quelle
0

In Javascript können Objekte wie ein Hash / eine Hashtabelle mit Schlüsselpaaren verwendet werden.

Wenn Ihr Schlüssel jedoch Zeichen enthält, die Javascript nicht als Namen kennzeichnen konnte, schlägt dies fehl, wenn versucht wird, wie eine Eigenschaft auf ein Objekt und nicht auf einen Schlüssel zuzugreifen.

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.

Bezeichner können manchmal Zeichen enthalten, die in Javascript nicht als Token / Bezeichner ausgewertet werden können. Daher ist es am besten, alle Bezeichner aus Gründen der Konsistenz in Zeichenfolgen zu setzen.

Michael Herndon
quelle
-2

Ich denke, die richtige Antwort auf Cheesos Frage ist, dass die Implementierung die Dokumentation übertroffen hat. Es wird keine Zeichenfolge mehr als Schlüssel benötigt, sondern etwas anderes, das entweder eine Zeichenfolge (dh in Anführungszeichen) oder (wahrscheinlich) alles sein kann, was als Variablenname verwendet werden kann. Ich denke, dies bedeutet, dass Sie mit einem Buchstaben beginnen, _ , oder $, und enthalten nur Buchstaben, Zahlen sowie $ und _.

Ich wollte den Rest für die nächste Person vereinfachen, die diese Frage mit der gleichen Idee wie ich besucht. Hier ist das Fleisch:

Variablennamen werden in JSON nicht interpoliert, wenn sie als Objektschlüssel verwendet werden (Danke Friedo!)

Breton, der "Bezeichner" anstelle von "Schlüssel" verwendete, schrieb: "Wenn ein Bezeichner zufällig ein reserviertes Wort ist, wird er als dieses Wort und nicht als Bezeichner interpretiert." Das mag wahr sein, aber ich habe es ohne Probleme versucht:

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

=> 6

Über die Verwendung von Anführungszeichen schrieb Quentin: "... aber das müssen Sie nicht, es sei denn, [der Schlüssel] enthält bestimmte Zeichen (oder Kombinationen von Zeichen, die es zu einem Schlüsselwort machen würden)."

Ich fand, dass der vorherige Teil (bestimmte Zeichen) mit dem @ -Zeichen wahr ist (tatsächlich denke ich, dass $ und _ die einzigen Zeichen sind, die den Fehler nicht verursachen):

var a = {a@b:1};

=> Syntaxfehler

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

=> 1

Aber die Klammer über Schlüsselwörter, wie ich oben gezeigt habe, ist nicht wahr.

Was ich wollte, funktioniert, weil der Text zwischen der Öffnung {und dem Doppelpunkt oder zwischen dem Komma und dem Doppelpunkt für nachfolgende Eigenschaften als nicht zitierte Zeichenfolge verwendet wird, um einen Objektschlüssel zu erstellen, oder, wie Friedo es ausdrückte, als Variablenname dort nicht. ' t interpoliert werden:

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

=> ABC123

Dave Scotese
quelle
-3

Wenn json Objekte beschreibt, erhalten Sie in der Praxis Folgendes

var foo = {};

var bar = 1;

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

also dann,

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

Selbst wenn Ihre Beispiele das gleiche Ergebnis liefern, würden ihre Entsprechungen im "Rohcode" dies nicht tun. Vielleicht deswegen?? Keine Ahnung, nur eine Idee.

Dave Archer
quelle
3
@David, Variablennamen werden in JS nicht interpoliert, wenn sie als Objektschlüssel verwendet werden. { bar: 'goodbye' }setzt den Schlüsselnamen nicht auf den Wert von bar, sondern nur bar. Die anderen haben Recht mit dem Grund, warum für die Spezifikation Anführungszeichen erforderlich sind: Sie soll Konflikte mit Schlüsselwörtern und Sonderzeichen vermeiden.
Friedo
-3

Dies kann die Datengröße verringern, wenn Anführungszeichen für Namen nur bei Bedarf zulässig sind

Shashank Joshi
quelle