Есть ли практическая причина использовать строки в кавычках для ключей 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


11
YAML не является расширенным набором JSON.
— Джон Гибб

для информации о том, почему: stackoverflow.com/questions/25974485/…
— Бен Пейдж
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.