Инструменты разработчика · JSON форматировщик и валидатор
Объектные литералы JavaScript против JSON: почему одинарные кавычки не проходят проверку
· Как это работает
JSON рабочий процесс разработчика проверка
Объект, напечатанный консолью JavaScript, выглядит как JSON, но обычно это не так. В этом посте перечислены точные различия (кавычки, ключи без кавычек, неопределенные функции) и показано, где каждое из них сбивает валидатор.
Оно вышло из консоли, так почему оно недействительно?
Оно вышло из консоли, так почему оно недействительно? — консоли разработчика отображают значения JavaScript как исходный текст JavaScript, а не как гарантированную сериализацию JSON. Скопированный объект может содержать имена свойств, строки в одинарных кавычках, `undefined` или аннотации, специфичные для браузера. Все это может быть понятно движку JavaScript или читателю, но при этом немедленно потерпеть неудачу в файле `.json`, грамматика которого намеренно меньше и не зависит от исполняемого кода.
Рассмотрим `{name: "Ada", active: true, missing: undefined}`. Фигурные скобки, двоеточие и логическое значение напоминают JSON, но первый пустой ключ уже нарушает правило объекта-члена, и `undefined` позже потерпит неудачу. ToolAcre сообщает о первом неподдерживаемом символе или значении в строке и столбце, поэтому преобразование лучше выполнять по порядку.
Строки должны использовать двойные кавычки
Строки должны заключаться в двойные кавычки — JSON определяет строку как символы, заключенные в `"`, с обратной косой чертой, где это необходимо. Одинарная кавычка не играет роли разделителя строк. Когда валидатор встречает `'Ada'`, он не начинает строку, а затем возражает против ее содержимого; он отвергает сам вводный апостроф. Это в равной степени относится и к именам свойств, и к строковым значениям, хотя JavaScript допускает любой стиль кавычек для своих собственных литералов.
Преобразование кавычек требует большей осторожности, чем глобальная замена каждого апострофа. Апостроф внутри текста, например `Ada's profile`, является обычным содержимым, если значение заключено в двойные кавычки, тогда как существующие двойные кавычки внутри этого содержимого должны быть экранированы. Действительная форма JSON — `"Ada's "profile""`.
Ключи должны быть строками в кавычках
Ключи должны быть заключены в строки — литералы объекта JavaScript допускают имена в стиле идентификатора, такие как `{name: 1}`, и вычисляемые имена, такие как `{[expression]: 1}`. JSON не допускает ни одного сокращения. После открывающей скобки или запятой следующий член должен начинаться со строки в двойных кавычках, за которой следует двоеточие. Допустимое представление — `{"name": 1}`. Валидатор, указывающий на `n`, определяет точное место, где требовалась котировка.
Заключение каждого ключа в кавычки также устраняет двусмысленность вокруг пробелов, дефисов и зарезервированных слов. Для JavaScript в этих случаях может потребоваться другой исходный синтаксис, но JSON использует одно согласованное правило: `"display-name"`, `"first name"` и `"default"` — все обычные имена членов. Цифровые клавиши тоже являются строками.
Значений JSON просто нет
Значений JSON просто не имеет — его словарь значений — это объект, массив, строка, число, `true`, `false` и `null`. Нет `undefined`, `NaN`, `Infinity`, функции, регулярного выражения, BigInt или литерала даты. Комментарии в грамматике отсутствуют, а числа не могут использовать шестнадцатеричные, двоичные, ведущие знаки плюс или числовые разделители JavaScript. Каждая заимствованная конструкция в конечном итоге достигает символа, который не может начинать или продолжать допустимое значение JSON.
Преобразование требует решения по данным, а не уловке правописания. Замените `undefined` на `null` только в том случае, если явное пустое значение соответствует контракту приложения; в противном случае удалите члена или укажите реальное значение. Кодируйте даты как согласованные строки, часто ISO 8601. Представлять неконечные числа согласно полученному API вместо изобретения токена JSON.
Рабочий пример: преобразование дампа консоли в действительный JSON
Рабочий пример: преобразование дампа консоли в действительный JSON — начните с `{name: 'Ada', active: true, score: NaN, updated: new Date()}`. Заключите `name`, `active`, `score` и `updated` в двойные кавычки. Измените значение имени на строку в двойных кавычках. Решите, что недоступная оценка должна быть `null`, и замените выражение конструктора фактической строкой метки времени, которую оно должно было создать. Теперь документ содержит только JSON членов и значений.
Готовая форма может иметь вид `{"name":"Ada","active":true,"score":null,"updated":"2026-03-21T10:00:00Z"}`. Проверяйте после каждой категории исправлений, поскольку первая ошибка может скрыть последующий синтаксис только для JavaScript. Форматирование принятого результата затем раскрывает его структуру без выполнения какого-либо дальнейшего преобразования.
Обратная ловушка — действительный JSON, который JavaScript будет читать по-другому, например, очень большие целые числа и ключ __proto__.
Обратная ловушка — действительный JSON может по-прежнему приобретать поведение или ограничения, специфичные для JavaScript, после анализа. Числа JSON не имеют встроенного ограничения точности в грамматике, но JSON.parse создает числовые значения JavaScript. Таким образом, целое число, выходящее за пределы безопасного диапазона, можно округлить без уведомления. Если важна каждая цифра, закодируйте идентификатор в виде строки или используйте синтаксический анализатор и тип данных, предназначенный для сохранения чисел произвольной точности, а не доверяйте успешной проверке синтаксиса.
Имя элемента `"__proto__"` также допустимо JSON, и JSON.parse создает его как собственное свойство данных. Проблемы могут начаться позже, если код приложения копирует проанализированные свойства в другой объект с небезопасным присваиванием или поведением слияния. Проверка подтверждает, что текст соответствует грамматике JSON; это не доказывает, что каждый ключ безопасен для каждого потребителя.
Что это не распространяется
Что здесь не распространяется — JSON5, JSONC и языки конфигурации, которые намеренно принимают комментарии, конечные запятые, имена без кавычек или строки в одинарных кавычках. Эти форматы решают различные проблемы разработки и требуют синтаксических анализаторов, реализующих собственные грамматики. Строгий валидатор JSON не должен молча переинтерпретировать их, поскольку принятие дополнительного синтаксиса может привести к тому, что его результат будет вводить в заблуждение для API, метаданных пакета и других мест назначения, которые действительно требуют стандарта JSON.
Это различие также исключает произвольную оценку JavaScript. Запуск вставленного текста через `eval` или конструктор функции просто для преобразования литерала объекта в данные может привести к выполнению методов получения, вызовов или других враждебных выражений. Если источник JavaScript является доверенным и находится под вашим контролем, сериализуйте фактическое значение с помощью JSON.stringify. Если источником является ненадежный текст, не выполняйте его.
Вывод: литерал — это код, JSON — данные.
Вывод: литерал — это код, JSON — данные — визуальное сходство не делает их грамматики взаимозаменяемыми. JSON требует строк и имен членов в двойных кавычках, допускает только небольшой фиксированный набор типов значений и не содержит комментариев или исполняемых выражений. Диагностика в виде строк и столбцов отмечает первое место, где скопированный источник покидает эту грамматику. Исправление этой точки и повторная проверка более надежны, чем применение широкого поиска и замены к дампу консоли.
Когда вы управляете значением JavaScript, сгенерируйте JSON с помощью JSON.stringify вместо копирования его консольного представления. Когда вы получаете текст, анализируйте его только с помощью синтаксического анализатора на предмет заявленного формата и никогда не выполняйте его как ярлык. Успешная проверка JSON устанавливает синтаксис, а не числовую точность, соответствие схемы или безопасную обработку последующих свойств.