Czy jest jakiś praktyczny powód, aby używać ciągów znaków w cudzysłowie dla kluczy JSON?

87

Według witryny json.org Crockforda obiekt JSON składa się z elementów członkowskich , które składają się z par .

Każda para składa się z ciągu i wartości , przy czym łańcuch jest zdefiniowany jako:

Łańcuch to sekwencja zera lub więcej znaków Unicode, umieszczona w podwójnych cudzysłowach, przy użyciu odwrotnych ukośników. Znak jest reprezentowany jako pojedynczy ciąg znaków. Ciąg jest bardzo podobny do ciągu w języku C lub Java.

Jednak w praktyce większość programistów nawet nie wie, że klucz JSON powinien być otoczony podwójnymi cudzysłowami, ponieważ większość przeglądarek nie wymaga używania cudzysłowów.

Czy warto zawracać sobie głowę otaczaniem JSON w podwójnych cudzysłowach?

Prawidłowy przykład:

{
  "keyName" : 34
}

W przeciwieństwie do inwalidów:

{
   keyName : 34
}
Mark Rogers
źródło
20
"Po co zawracać sobie głowę robieniem tego dobrze?" Jest to rodzaj leniwego myślenia, które prowadzi do witryn obciążonych nieprawidłowymi znacznikami. Przyszłościowe kod w przypadku niektórych przeglądarka nie wymagają cudzysłowów.
meagar
21
"Po co zawracać sobie głowę robieniem tego dobrze?" - Po co zawracać sobie głowę konwencją, której nikt inny nie robi, jeśli nie ma rzeczywistej korzyści? Być może mylisz leniwe myślenie z pragmatyzmem.
Mark Rogers,
15
@Mark - „tego nie robi nikt inny”… skąd wziął się ten pomysł? serializator JSON wbudowany w każdą główną platformę wykonuje prawidłowe cytowanie.
Nick Craver
7
@Mark Rogers Funkcja json_encode PHP tworzy poprawny kod JSON, na przykład z podwójnymi cudzysłowami. Może myślisz o literałach obiektów w JavaScript? To prawda, że ​​działają one bez cytowania kluczy, ale to nie jest JSON.
JAL
9
Dla przypomnienia, lata temu, kiedy to opublikowałem, byłem zdezorientowany różnicą między JSON a notacją dosłowną obiektu, jak sugerował @JAL. Obaj mają bardzo podobną składnię, co ostatecznie doprowadziło do pewnego zamieszania w opisie problemu.
Mark Rogers

Odpowiedzi:

155

Prawdziwy powód, dla którego klucze JSON powinny być w cudzysłowach, wynika z semantyki identyfikatorów ECMAScript 3.

Zarezerwowanych słów nie można używać jako nazw właściwości w literałach obiektów bez cudzysłowów, na przykład:

({function: 0}) // SyntaxError
({if: 0}) // SyntaxError
({true: 0}) // SyntaxError
// etc...

Chociaż jeśli używasz cudzysłowów, nazwy właściwości są prawidłowe:

({"function": 0}) // Ok
({"if": 0}) // Ok
({"true": 0}) // Ok

Własny Crockford wyjaśnia to w tym wykładzie , chcieli, aby standard JSON był prosty i nie chcieli mieć wszystkich tych ograniczeń semantycznych:

....

Wtedy odkryliśmy problem z nazwami bez cytatów. Okazuje się, że ECMA Script 3 ma politykę dotyczącą słów zastrzeżonych. Zastrzeżone słowa należy cytować w pozycji kluczowej, co jest naprawdę uciążliwe. Kiedy doszedłem do sformułowania tego w standardzie, nie chciałem umieszczać wszystkich zastrzeżonych słów w standardzie, ponieważ wyglądałoby to naprawdę głupio.

W tamtym czasie starałem się przekonać ludzi: tak, możesz pisać aplikacje w JavaScript, to faktycznie zadziała i to jest dobry język. Nie chciałem więc jednocześnie powiedzieć: i spójrz na tę naprawdę głupią rzecz, którą zrobili! Postanowiłem więc zamiast tego zacytować klucze.
W ten sposób nie musimy nikomu mówić o tym, jak to jest.

Dlatego do dziś klucze są cytowane w formacie JSON.

...

Standard ECMAScript 5th Edition rozwiązuje ten problem, teraz w implementacji ES5 nawet zastrzeżone słowa mogą być używane bez cudzysłowów, zarówno w literałach obiektu, jak i dostępie do elementów członkowskich ( obj.functionOk w ES5).

Tak dla przypomnienia, ten standard jest obecnie wdrażany przez dostawców oprogramowania, możesz zobaczyć, które przeglądarki zawierają tę funkcję w tej tabeli zgodności (zobacz słowa zastrzeżone jako nazwy właściwości )

Christian C. Salvadó
źródło
1
@Mark, nie ma za co. Należy pamiętać, że JSON to po prostu niezależny od języka format wymiany danych, nawet jeśli jego składnia została zainspirowana składnią Javascript Object Literal, istnieją między nimi różnice (znacznie więcej niż tylko cytowane klucze).
Christian C. Salvadó,
2
@CMS, więc dlaczego muszą to być tylko podwójne cudzysłowy? Dlaczego pojedyncze cudzysłowy są nieprawidłowe w formacie JSON?
Pacerier
1
Pojedyncze cudzysłowy są niedozwolone, aby standard JSON był tak prosty, jak to tylko możliwe. JSON musi być tylko podzbiorem JavaScript, nie musi implementować jak największej ilości JavaScript.
thomasrutter
Specyfikacja superzestawu JSON5 jest zgodna ze składnią ES5 i dlatego obsługuje między innymi klucze niecytowane. Biblioteka ma kompatybilne parsei stringifymetody.
Inigo
W tym odnośniku do tabeli zgodności (na dole odpowiedzi) wpis Zarezerwowane słowa znajduje się w sekcji Rozszerzenia literału obiektu / tablicy . I TL; DR, wszystkie wymienione przeglądarki (wszystko, o czym słyszałeś i około 20 więcej), wszystkie mówią „Tak”.
i336_
16

Tak, jest to nieprawidłowy JSON i w wielu przypadkach zostanie odrzucony, na przykład jQuery 1.4+ ma kontrolę, która powoduje dyskretne niepowodzenie niezacytowanego JSON. Dlaczego nie zachować zgodności?

Weźmy inny przykład:

{ myKey: "value" }
{ my-Key: "value" }
{ my-Key[]: "value" }

... wszystko to byłoby poprawne w przypadku cudzysłowów, dlaczego by nie być spójnym i używać ich we wszystkich przypadkach, eliminując możliwość wystąpienia problemu?

Jeszcze jeden typowy przykład ze świata twórców stron internetowych: istnieją tysiące przykładów nieprawidłowego kodu HTML, który renderuje się w większości przeglądarek ... czy to sprawia, że ​​debugowanie lub konserwacja jest mniej bolesna? Wcale nie, wręcz przeciwnie.

Również @ Matthew zwraca uwagę na to, co najlepsze w komentarzach poniżej, to już się nie udaje, niecytowane klawisze będą powodować błąd składni JSON.parse()we wszystkich głównych przeglądarkach (i wszystkich innych, które implementują go poprawnie), możesz to przetestować tutaj .

Nick Craver
źródło
Tak, miałem kilka starych aplikacji Ajax generujących po stronie serwera schonky json, które nie powiodły się po aktualizacji do jquery 1.4 z powodu braku podwójnych cudzysłowów wokół nazw kluczy.
JAL
Możesz chcieć dodać, że wszystkie główne przeglądarki JSON.parserównież poprawnie ją odrzucą.
Matthew Flaschen
Jestem ciekawy, w jakim dokładnie przypadku JQuery 1.4 po cichu zawiedzie z tego typu nieprawidłowym jsonem?
Mark Rogers,
1
@Mark - w każdym razie nie jest poprawnie cytowany lub zawiera nieprawidłowe znaki ... w zasadzie nie powiedzie się z każdym nieprawidłowym JSON.
Nick Craver
To ciekawe, to nie było moje doświadczenie z JQuery 1.4. Co więcej, nie sądzę, że jquery jest odpowiedzialne za tworzenie obiektów json, czyż nie to robi interpreter javascript przeglądarki? Czy masz na myśli deserializację JQuery JSON?
Mark Rogers
-4

YAML, który w rzeczywistości jest nadzbiorem JSON, obsługuje to, co chcesz zrobić. Chociaż jest to nadzbiór, pozwala Ci zachować tak prostą, jak chcesz.

YAML to powiew świeżego powietrza i warto poświęcić czas, aby mu się przyjrzeć. Najlepszym miejscem do rozpoczęcia jest tutaj: http://en.wikipedia.org/wiki/YAML

Istnieją biblioteki dla każdego języka pod słońcem, w tym JS, np. Https://github.com/nodeca/js-yaml

user1649339
źródło
11
YAML nie jest nadzbiorem JSON.
John Gibb
aby dowiedzieć się, dlaczego: stackoverflow.com/questions/25974485/ ...
Ben Strona