in JSON, perché ogni nome viene citato?


91

La specifica JSON dice che JSON è un oggetto o un array. Nel caso di un oggetto,

Una struttura di oggetti è rappresentata come una coppia di parentesi graffe che circondano zero o più coppie nome / valore (o membri). Un nome è una stringa. ...

E più tardi, la specifica dice che una stringa è racchiusa tra virgolette.

Perché?

Quindi,

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

e non

{Property1:"Value1",Property2:18}

Domanda 1 : perché non consentire al nome nelle coppie nome / valore di essere identificatori non quotati?


Domanda 2 : C'è una differenza semantica tra le due rappresentazioni sopra, quando valutate in Javascript?


1
@Bruno: Potresti parlare di XML allo stesso modo ... e purtroppo, alcuni là fuori potrebbero provare a usare XML come linguaggio di programmazione ...
Mike DeSimone

2
+1 ... sembra una contraddizione particolare .... "con virgolette" lo rende JSON standard, ma non funziona con eval()(cioè javascript).
skaffman

2
@bruno, no. se lo espandi, diventa "in Javascript Object Notation" che va bene
Dave Archer

2
@skaffman - Funzionerà se valutato in JavaScript.
Quentin

1
@Bruno - JSON è un formato dati. "In JSON" significa - con i dati formattati secondo le specifiche.
Cheeso

Risposte:


57

Domanda 1: perché non consentire al nome nelle coppie nome / valore di essere identificatori non quotati?

La filosofia di progettazione di JSON è "Keep it simple"

"Cita nomi con "" è molto più semplice di "Puoi citare nomi con "o 'ma non è necessario, a meno che non contengano determinati caratteri (o combinazioni di caratteri che la renderebbero una parola chiave) e / 'o "potrebbe dover essere citato a seconda su quale delimitatore hai selezionato " .

Domanda 2: C'è una differenza semantica tra le due rappresentazioni sopra, quando valutate in Javascript?

No. In JavaScript sono identici.


3
No, non è corretto. CMS ha la risposta corretta. Questa risposta è solo un simpatico effetto collaterale del vero motivo. Oltre ad essere più semplice da spiegare, è anche più semplice scrivere un parser, poiché è possibile riutilizzare le regole di analisi per le stringhe sugli identificatori.
Breton

e a parte questo, c'è una leggera differenza semantica nel fatto che se un identificatore sembra essere una parola riservata, viene interpretato come quella parola piuttosto che come un identificatore.
Breton

2
+1 sulla risposta di CMS, è corretto. Le virgolette doppie non sono una convenzione del codice, ma si desidera evitare le parole riservate come chiavi nell'oggetto. Ad esempio: {property1: "abc", this: "def"} è SBAGLIATO (questa è una parola chiave riservata)
Sorin Mocanu

Domanda 2 : Una piccola differenza in Javascript quando si usa JSON.parsela funzione: JSON.parse('{"a":1}') funziona bene , perché JSON.parse('{a:1}')si solleva un'eccezione .
nhnghia

@nhnghia - La domanda 2 riguarda la valutazione del codice sorgente come JavaScript , non JSON. JSON.parseè un parser JSON implementato in JavaScript, non è un parser JavaScript.
Quentin

134

Lascio una citazione da una presentazione che Douglas Crockford (il creatore dello standard JSON) ha fatto a Yahoo.

Parla di come ha scoperto JSON e, tra le altre cose, perché ha deciso di utilizzare le chiavi tra virgolette :

.... Fu allora che scoprimmo il problema del nome non quotato. Si scopre che ECMA Script 3 ha una politica di parole riservate whack. Le parole riservate devono essere citate nella posizione chiave, il che è davvero un fastidio. Quando sono arrivato a formularlo in uno standard, non volevo mettere tutte le parole riservate nello standard, perché sarebbe sembrato davvero stupido.

A quel tempo, stavo cercando di convincere le persone: sì, puoi scrivere applicazioni in JavaScript, in realtà funzionerà ed è un buon linguaggio. Non volevo dire, quindi, allo stesso tempo: e guarda che cosa davvero stupida hanno fatto! Quindi ho deciso, invece, di citare solo le chiavi.
In questo modo, non dobbiamo dire a nessuno di quanto sia schifoso.

Ecco perché, fino ad oggi, le chiavi sono quotate in JSON.

Puoi trovare il video completo e la trascrizione qui .


Ummm ... il creatore dello standard JSON ?! Credo che sia un'esagerazione. JSON è la notazione dell'oggetto JavaScript e proviene dalle specifiche Javascript (ECMA).
Sorin Mocanu

42
@ Sorin: non confondere JSON con i valori letterali dell'oggetto JavaScript. JSON è un formato di scambio di dati indipendente dalla lingua, proposto da Crockford nel 2006 ( tools.ietf.org/html/rfc4627 ), la sua grammatica è diversa dai letterali dell'oggetto JavaScript ( bclary.com/2004/11/07/#a-11.1 .5 ), in pratica consentendo solo chiavi stringa ei valori DEVONO essere un oggetto , un array , un numero , una stringa o uno dei seguenti nomi letterali: false , null true . I letterali oggetto in JavaScript possono avere chiavi come identificatori , stringhe oNumero letterale e il valore può essere qualsiasi tipo di espressione ...
Christian C. Salvadó

@CMS E il JavaScript di oggi consente identificatori abbreviati all'interno di espressioni del costruttore di oggetti, ad esempio:, { a }dove la proprietà 'a' copia il valore di una variabile globale o locale 'a'.
Hydroper

@CMS E ci sono anche chiavi calcolate:{[key]: value}
Hydroper

0

Sia gli :spazi bianchi che gli spazi sono consentiti negli identificatori. Senza le virgolette, ciò causerebbe ambiguità quando si cerca di determinare cosa costituisce esattamente l'identificatore.


0

In javascript gli oggetti possono essere usati come una tabella hash / hash con coppie di chiavi.

Tuttavia, se la tua chiave ha caratteri che javascript non è in grado di tokenizzare come nome, fallirà quando provi ad accedere come una proprietà su un oggetto piuttosto che su una chiave.

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.

gli identificatori a volte possono avere caratteri che non possono essere valutati come token / identificatore in javascript, quindi è meglio mettere tutti gli identificatori in stringhe per coerenza.


-2

Penso che la risposta giusta alla domanda di Cheeso sia che l'implementazione ha superato la documentazione. Non richiede più una stringa come chiave, ma piuttosto qualcos'altro, che può essere una stringa (cioè quotata) o (probabilmente) qualsiasi cosa possa essere usata come nome di variabile, che immagino significhi iniziare con una lettera, _ o $ e includi solo lettere, numeri e $ e _.

Volevo semplificare il resto per la prossima persona che visita questa domanda con la stessa idea che ho fatto io. Ecco la carne:

I nomi delle variabili non vengono interpolati in JSON se usati come chiave oggetto (Grazie Friedo!)

Breton, usando "identificatore" invece di "chiave", scrisse che "se un identificatore è una parola riservata, viene interpretato come quella parola piuttosto che come un identificatore". Potrebbe essere vero, ma l'ho provato senza problemi:

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

=> 6

Sull'uso delle virgolette, Quentin ha scritto "... ma non è necessario, a meno che [la chiave] non contenga determinati caratteri (o combinazioni di caratteri che la renderebbero una parola chiave)"

Ho scoperto che la prima parte (alcuni caratteri) è vera, usando il segno @ (infatti, penso che $ e _ siano gli unici caratteri che non causano l'errore):

var a = {a@b:1};

=> Errore di sintassi

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

=> 1

ma la parentesi sulle parole chiave, come ho mostrato sopra, non è vera.

Quello che volevo funziona perché il testo tra l'apertura {e i due punti, o tra la virgola e i due punti per le proprietà successive è usato come una stringa non quotata per rendere la chiave di un oggetto, o, come ha detto Friedo, un nome di variabile lì non ' t ottenere interpolato:

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

=> ABC123


-3

Se json descrive gli oggetti, in pratica ottieni quanto segue

var foo = {};

var bar = 1;

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

allora,

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

quindi, anche se i tuoi esempi producono lo stesso risultato, i loro equivalenti in "codice grezzo" non lo farebbero. Forse è per questo? boh, solo un'idea.


3
@David, i nomi delle variabili non vengono interpolati in JS quando usati come chiave oggetto. { bar: 'goodbye' }non imposterà il nome della chiave sul valore di bar, sarà solo bar. Gli altri hanno ragione sul motivo per cui le specifiche richiedono virgolette: è per evitare conflitti di parole chiave e caratteri speciali.
friedo

-3

Può ridurre la dimensione dei dati se le virgolette sul nome sono consentite solo quando necessario

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.