Есть ли практическая причина использовать строки в кавычках для ключей JSON?

87

Согласно Крокфорду в json.org , JSON объект состоит из элементов , которые состоят из пар .

Каждая пара состоит из строки и значения , при этом строка определяется как:

Строка - это последовательность из нуля или более символов Юникода, заключенная в двойные кавычки с использованием экранирования обратной косой черты. Символ представлен в виде односимвольной строки. Строка очень похожа на строку C или Java.

Но на практике большинство программистов даже не знают, что ключ JSON должен быть заключен в двойные кавычки, потому что большинство браузеров не требуют использования двойных кавычек.

Есть ли смысл заключать JSON в двойные кавычки?

Действительный пример:

{
  "keyName" : 34
}

В отличие от инвалида:

{
   keyName : 34
}
Марк Роджерс
источник
20
"Зачем делать это правильно?" Это вид ленивого мышления, который приводит к тому, что веб-сайты нагружены недопустимой разметкой. Перспективный код в случае , если некоторые браузеры действительно требуют двойных кавычек.
meagar
21
"Зачем делать это правильно?" - Зачем следовать условности, которую никто другой не делает, если в этом нет реальной выгоды? Возможно, вы путаете ленивое мышление с прагматизмом.
Марк Роджерс
15
@Mark - "что никто другой не делает" ... откуда вы взяли эту идею? сериализатор JSON, встроенный в каждую крупную платформу, правильно цитирует.
Ник Крейвер
7
Функция @Mark Rogers PHP json_encode создает действительный JSON, например, со строками в двойных кавычках. Может быть, вы думаете об объектных литералах в JavaScript? Верно, что они работают без цитирования ключей, но это не JSON.
JAL
9
Для записи, много лет назад, когда я опубликовал это, меня смутила разница между JSON и обозначением объектных литералов, как предлагал @JAL. Оба имеют очень похожий синтаксис, что в конечном итоге привело к некоторой путанице в описании проблемы.
Марк Роджерс

Ответы:

155

Настоящая причина того, почему ключи JSON должны быть в кавычках, основывается на семантике идентификаторов ECMAScript 3.

Зарезервированные слова нельзя использовать в качестве имен свойств в объектных литералах без кавычек, например:

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

Хотя, если вы используете кавычки, имена свойств действительны:

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

Собственный Крокфорд объясняет это в этом выступлении , они хотели сохранить простоту стандарта JSON и не хотели бы налагать на него все эти семантические ограничения:

....

Именно тогда мы обнаружили проблему с именем без кавычек. Оказывается, в сценарии ECMA 3 используется политика зарезервированных слов для взлома. Зарезервированные слова необходимо цитировать в ключевой позиции, что действительно неприятно. Когда я добрался до формулировки этого стандарта, я не хотел помещать все зарезервированные слова в стандарт, потому что это выглядело бы очень глупо.

В то время я пытался убедить людей: да, вы можете писать приложения на JavaScript, он действительно будет работать, и это хороший язык. Тогда я не хотел одновременно говорить: и посмотрите на эту действительно глупую вещь, которую они сделали! Поэтому я решил вместо этого просто процитировать ключи.
Таким образом, нам не нужно никому рассказывать о том, насколько это круто.

Вот почему по сей день ключи цитируются в JSON.

...

Стандарт ECMAScript 5th Edition исправляет это, теперь в реализации ES5 даже зарезервированные слова могут использоваться без кавычек как в литералах объектов, так и в доступе к членам ( obj.functionнормально в ES5).

Для записи, этот стандарт внедряется в наши дни поставщиками программного обеспечения, вы можете увидеть, какие браузеры включают эту функцию в этой таблице совместимости (см. Зарезервированные слова как имена свойств )

Кристиан К. Сальвадо
источник
1
@Mark, пожалуйста. Имейте в виду, что JSON - это просто не зависящий от языка формат обмена данными, даже если его синтаксис был вдохновлен синтаксисом Javascript Object Literal, между ними есть различия (гораздо больше, чем просто цитируемые ключи).
Christian C. Salvadó
2
@CMS, так почему это должны быть только двойные кавычки? Почему одинарные кавычки в JSON недопустимы?
Pacerier
1
Использование одинарных кавычек запрещено, чтобы стандарт JSON оставался максимально простым. JSON должен быть только подмножеством Javascript, ему не нужно реализовывать как можно больше Javascript.
thomasrutter
JSON5 суперсет спецификацию придерживается синтаксиса ES5 и , таким образом , поддерживает некотируемые ключи среди других вещей. В библиотеке есть совместимые parseи совместимые stringifyметоды.
Иниго
В этой ссылке на таблицу совместимости (внизу ответа) запись « Зарезервированные слова» находится в разделе « Расширения литералов объекта / массива ». И TL; DR, все перечисленные браузеры (все, о которых вы слышали, и еще около 20) все говорят «Да».
i336_
16

Да, это недопустимый JSON, и во многих случаях он будет отклонен, например, в jQuery 1.4+ есть проверка, которая заставляет JSON без кавычек молча терпеть неудачу. Почему бы не соответствовать требованиям?

Возьмем другой пример:

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

... все они будут действительны в кавычки, то почему бы не быть последовательным и использовать их во всех случаях, исключая возможность проблемы?

Еще один распространенный пример в мире веб-разработчиков: существуют тысячи примеров недействительного HTML, который отображается в большинстве браузеров ... делает ли это менее болезненным отладку или поддержку? Вовсе нет, совсем наоборот.

Также @ Matthew делает лучшее из всех в комментариях ниже, это уже не работает, ключи без кавычек будут вызывать синтаксическую ошибку JSON.parse()во всех основных браузерах (и любых других, которые реализуют это правильно), вы можете проверить это здесь .

Ник Крейвер
источник
Да, у меня было несколько старых приложений ajax, генерирующих серверную часть schonky json, которые не работали при обновлении до jquery 1.4 из-за отсутствия двойных кавычек вокруг имен ключей.
JAL
Вы можете добавить, что все основные браузеры JSON.parseтакже правильно отклонят его.
Мэтью Флашен
Мне любопытно, в каком именно случае JQuery 1.4 молча выйдет из строя с этим типом недопустимого json?
Марк Роджерс
1
@Mark - в любом случае он неправильно процитирован или содержит недопустимые символы ... в основном он не работает с любым недопустимым JSON.
Ник Крейвер
Это интересно, у меня не было такого опыта работы с JQuery 1.4. Кроме того, я не думаю, что jquery отвечает за создание объектов json, разве это не то, что делает интерпретатор javascript браузера? Вы имеете в виду десериализацию json в JQuery?
Марк Роджерс
-4

YAML, который на самом деле является расширенным набором JSON, поддерживает то, что вы хотите делать. Хотя это расширенный набор, он позволяет сделать его настолько простым, насколько вы хотите.

YAML - это глоток свежего воздуха, и, возможно, стоит потратить время на то, чтобы взглянуть на него. Лучшее место для начала здесь: http://en.wikipedia.org/wiki/YAML

Существуют библиотеки для всех языков под солнцем, включая JS, например https://github.com/nodeca/js-yaml

user1649339
источник
11
YAML не является расширенным набором JSON.
Джон Гибб
для информации о том, почему: stackoverflow.com/questions/25974485/…
Бен Пейдж