Должны ли ключи JSON быть заключены в кавычки?

236

Пример: допустим ли следующий код для спецификации JSON ?

{
    precision: "zip"
}

Или я всегда должен использовать следующий синтаксис? (А если так, то почему?)

{
    "precision": "zip"
}

Я действительно не нашел что-то об этом в спецификациях JSON. Хотя они используют кавычки вокруг своих ключей в своих примерах.

christianvuerings
источник

Ответы:

147

Да, вам нужны кавычки. Это сделать проще и избежать необходимости иметь другой способ ускользания яваскрипта зарезервированных ключевых слов, то есть {for:"foo"}.

cobbal
источник
12
Цитаты не проще во многих ситуациях, таких как файлы конфигурации, которые редактируются вручную. К сожалению, использование JSON (и его неправильное использование) в качестве почти универсального формата обмена данными заключается в том, что он имеет особенности, специфичные для Javascript.
Мигель
12
Реальная причина - проверьте этот ответ тоже - stackoverflow.com/questions/4201441/…
TechMaze
3
Tl; dr: они не хотели иметь дело с ограничением ECMAScript для (не заключенных в кавычки) зарезервированных ключевых слов в качестве ключей, поэтому им просто требовалось заключить в кавычки все ключи.
BallpointBen
136

Вы правильно используете строки в качестве ключа. Вот выдержка из RFC 4627 - Тип приложения / json Media для нотации объектов JavaScript (JSON)

2.2. Объекты

Структура объекта представляется в виде пары фигурных скобок, окружающих ноль или более пар имя / значение (или членов). Имя - это строка . После каждого имени стоит двоеточие, отделяющее имя от значения. Одна запятая отделяет значение от следующего имени. Имена внутри объекта ДОЛЖНЫ быть уникальными.

object = begin-object [ member *( value-separator member ) ] end-object

member = string name-separator value

[...]

2.5. Струны

Представление строк аналогично соглашениям, используемым в семействе языков программирования C. Строка начинается и заканчивается кавычками. [...]

string = quotation-mark *char quotation-mark

quotation-mark = %x22 ; "

Прочитайте весь RFC здесь .

PatrikAkerstrand
источник
11
И закончить мысль, раздел 2.5 говорит: A string begins and ends with quotation marks..
Ракслице
13

С 2.2. Объекты

Структура объекта представляется в виде пары фигурных скобок, окружающих ноль или более пар имя / значение (или членов). Имя - это строка.

и с 2.5. Струны

Строка начинается и заканчивается кавычками.

Поэтому я бы сказал, что в соответствии со стандартом: да, вы всегда должны цитировать ключ (хотя некоторые парсеры могут быть более прощающими)

Cebjyre
источник
0

Да, они делают. Но если вам нужно иначе, оформите JSON5 .

JSON5 - это расширенный набор JSON, который допускает синтаксис ES5, включая:

  • ключи без кавычек
  • одиночные кавычки, экранированные и многострочные строки
  • альтернативные форматы чисел
  • Комментарии
  • дополнительные пробелы

Реализация ссылок JSON5 ( json5пакет npm ) предоставляет JSON5объект parseи stringifyметоды с теми же аргументами и семантикой, что и у встроенного JSONобъекта.

Иниго
источник
-2

Поскольку вы можете поставить пунктирную нотацию parent.child и вам не нужно указывать parent ["child"], который также является допустимым и полезным, я бы сказал, что оба способа технически приемлемы. Все парсеры должны работать в обоих направлениях. Если вашему парсеру не нужны кавычки на ключах, то, вероятно, лучше не ставить их (экономит место). Имеет смысл называть их строками, потому что это то, чем они являются, и, поскольку квадратные скобки дают вам возможность использовать значения для ключей, по сути, имеет смысл не делать этого. В Json вы можете положить ...

>var keyName = "someKey";
>var obj = {[keyName]:"someValue"};

>obj
Object {someKey: "someValue"}

просто без проблем, если вам нужно значение для ключа, и ни одна из кавычек не будет работать, поэтому, если это не так, вы не сможете, так что вы не будете так «вам не нужны кавычки для ключей». Даже если правильно сказать, что они технически струны. Логика и использование утверждают иначе. Он также официально не выводит Object {"someKey": "someValue"} для объекта obj в нашем примере, запускаемого из консоли любого браузера.

Мастер Джеймс
источник
2
Как принятый ответ, так и RFC, определяющий JSON, говорят, что кавычки обязательны.
Кит Томпсон
Это правда, но стоит отметить, что это логически не нужно. Я полагаю, что вывод JavaScript Object Notation из всех консолей браузера неверен, и мы должны сказать кому-нибудь, чтобы это исправить. Возможно, то, что выводит консоль браузера для объекта, не является JSON, поэтому, возможно, JSON, как определяет спецификация, не нужен и не реализован таким образом в большинстве мест. В любом случае, я просто хотел привести аргумент, который смотрит на факты в другом свете. В самом деле, может быть, спецификацию следует изменить, тогда «цитируемые ключи» просто не нужны нигде, что важно для меня лично. (Это просто не используется на практике.)
Мастер Джеймс
2
Вы смешиваете три разные вещи: JSON, литералы объектов JavaScript и вывод консоли инструментов разработчика браузера. Когда вы вводите свой текст objв консоли, браузер отображает некоторое удобочитаемое представление объекта. Он может отображать его как литерал объекта (как это было в вашем примере) или использовать другое представление, даже интерактивное. Литералы объекта JavaScript не требуют кавычек вокруг имени ключа, если ключ является допустимым идентификатором, а не зарезервированным словом. Однако JSON всегда требует кавычек вокруг имен ключей.
Майкл Гири
3
В качестве дальнейших примеров objпопробуйте вместо ввода в консоли JSON.stringify(obj). Теперь вы увидите действительное JSON-представление объекта, дополненное кавычкой с именем ключа. И наоборот, чтобы увидеть, является ли строка допустимым JSON, попробуйте JSON.parse(string). Если ключи не указаны, это приведет к исключению. Например,JSON.parse('{"a":"b"}') удастся, но не JSON.parse('{a:"b"}')получится.
Майкл Гири
1
ОТО, ваше использование var obj = {[keyName]:"someValue"};очень интересно! Я не знал, что вы могли бы сделать это в литерале объекта JavaScript. Немного проверки показывает, что это что-то новое в ES6 - вы не могли сделать это в ES5.
Майкл Гири