В чем разница между JSON и Object Literal Notation?

221

Может кто-нибудь сказать мне, в чем заключается основное различие между объектом JavaScript, определенным с помощью Object Literal Notation и объекта JSON ?

Согласно книге на JavaScript это говорит, что это объект, определенный с помощью нотации объекта :

var anObject = {
    property1 : true,
    showMessage : function (msg) { alert(msg) }
};

Почему в этом случае это не объект JSON? Только потому, что это не определяется с помощью кавычек?

pencilCake
источник
20
«Почему это не объект JSON в этом случае?»: Потому что ваши ключи должны быть строками, а функция не является допустимым значением JSON.
Мэтт
3
Возможный дубликат Каковы различия между JSON и JavaScript-объектом?
Гонки легкости на орбите

Ответы:

248

Давайте сначала уточнить, что такое JSON . JSON - это текстовый , независимый от языка формат обмена данными, очень похожий на XML, CSV или YAML.

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

Такие форматы обычно не зависят от языка, то есть они могут обрабатываться Java, Python, JavaScript, PHP, как вы это называете.

С другой стороны, JavaScript - это язык программирования. Конечно, JavaScript также предоставляет способ определения / описания данных, но синтаксис очень специфичен для JavaScript.

В качестве встречного примера у Python есть концепция кортежей , их синтаксис есть (x, y). JavaScript не имеет ничего подобного.


Давайте посмотрим на синтаксические различия между объектными литералами JSON и JavaScript.

JSON имеет следующие синтаксические ограничения:

  • Ключи объекта должны быть строками (т.е. символьная последовательность, заключенная в двойные кавычки)" ).
  • Значения могут быть следующими:
    • строка
    • число
    • объект (JSON)
    • массив
    • true
    • false
    • null
  • Дублирующиеся ключи ( {"foo":"bar","foo":"baz"}) дают неопределенные, специфичные для реализации результаты; спецификация JSON специально не определяет их семантику

В JavaScript объектные литералы могут иметь

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

Зная, что, просто взглянув на синтаксис , ваш пример не является JSON по двум причинам:

  1. Ваши ключи не являются строками (литералами). Это идентификаторы имен .
  2. Вы не можете назначить функцию в качестве значения «объекту JSON» (потому что JSON не определяет синтаксис для функций).

Но самое главное, повторить мое объяснение с самого начала: вы находитесь в контексте JavaScript. Вы определяете объект JavaScript. Если таковой имеется, «объект JSON» может содержаться только в строке:

 var obj = {foo: 42}; // creates a JavaScript object (this is *not* JSON)
 var json = '{"foo": 452}'; // creates a string containing JSON

То есть, если вы пишете исходный код JavaScript и не имеете дело со строкой , вы не имеете дело с JSON. Возможно, вы получили данные в виде JSON (например, через ajax или чтение из файла), но как только вы или используемая вами библиотека проанализировали их, это больше не JSON.


Только потому, что объектные литералы и JSON выглядят одинаково , это не значит, что вы можете называть их взаимозаменяемо. Смотрите также Там нет такого понятия, как "JSON Object" .

Феликс Клинг
источник
8
Также обратите внимание, что JSON является подмножеством объектной буквенной нотации
Шон Кинси
14
@SeanKinsey: За исключением того, что это не так: timelessrepo.com/json-isnt-a-javascript-subset
mpen
1
Возможно, стоит отметить, что обычно вы ожидаете литерал объекта JavaScript в контексте, где комментарии являются законными, а спецификация JSON не допускает комментарии (см. Этот пост .
Брайан Генри,
ключи в литерал объекта всегда являются строками, несмотря на то, что вы используете "" или нет.
сверхобмена
2
@overexchange: «ключи в литерал объекта всегда являются строками». Здесь вы смешиваете две вещи, но я не могу винить вас, потому что я также не провел здесь четкую линию. Вы должны различать литерал объекта и значение объекта . Буквальным является последовательность символов , вы пишете в исходном коде. Значение является то , что создается путем интерпретации исходного кода. Объектный литерал (синтаксис) позволяет вам использовать имена идентификаторов , строковые литералы или числовые литералы . Вы правы, что во время выполнения все они преобразуются в строки (но теперь у нас есть и символы).
Феликс Клинг
41

JSON имеет гораздо более ограниченный синтаксис, включая:

  • Ключевые значения должны быть указаны
  • Строки должны быть заключены в кавычки, "а не'
  • У вас есть более ограниченный диапазон значений (например, не разрешены функции)
Quentin
источник
1
Понравилось это "функция не разрешена".
Каран Кау
Комментарии также не допускаются. По сомнительным причинам. (Слышал, что их допрашивали несколько раз.) Это главное различие, которое я бы сказал.
user7610
15

На самом деле не существует такого понятия, как «объект JSON».

Спецификация JSON - это синтаксис для кодирования данных в виде строки. То, что люди называют «JSON-объект» (в javascript), на самом деле является обычным javascript-объектом, который (вероятно) был десериализован из допустимой строки JSON, и его можно легко повторно сериализовать как допустимую строку JSON. Обычно это означает, что он содержит только данные (а не функции). Это также означает, что даты отсутствуют, потому что в JSON нет типа даты (вероятно, самая болезненная вещь в JSON;)

Более того, (побочный характер ...), когда люди говорят о «объекте JSON», они почти всегда имеют в виду данные, которые имеют «фигурные скобки» на верхнем уровне. Это хорошо соответствует объекту javascript. Однако спецификация JSON не требует наличия единственного объекта «фигурных скобок» на верхнем уровне строки JSON. Для JSON вполне допустимо иметь список на верхнем уровне или даже иметь только одно значение. Таким образом, хотя каждый «объект JSON» соответствует действительному JSON, не все допустимые строки JSON соответствуют тому, что мы назвали бы «объектом JSON»! (потому что строка может представлять список или атомарное значение)

Ник Перкинс
источник
5
В вашем ответе есть ошибка: недопустимо использование JSON атомарного значения на верхнем уровне. JSON позволяет вершине быть объектом или массивом, но не более того. Стандарт RFC4627 описывает грамматику JSON как JSON-text = object / array.
Рори О'Кейн,
9

Согласно JSON в JavaScript ,

JSON является подмножеством объектной литеральной нотации JavaScript.

Другими словами, допустимый JSON также является действительной буквенной нотацией объекта JavaScript, но не обязательно наоборот.

В дополнение к чтению документации , как предложил @Filix King, я также предлагаю поиграть с онлайн-валидатором JSON JSONLint . Вот как я узнал, что ключи объектов JSON должны быть строками.

ma11hew28
источник
2
Просто чтобы заметить: это не точное подмножество , есть некоторые строки JSON, которые были недопустимы как литералы объекта JS
Bergi
5

SON JSON : обезжиренная альтернатива XML

JSON получил широкое распространение среди людей, которые обнаружили, что это значительно облегчает создание распределенных приложений и сервисов. Официальный тип интернет - СМИ для JSON это application/json RFC 4627. В именах файлов JSON используется расширение .json.


► JavaScript Object Notation ( JSON) - это легкий текстовый формат обмена данными, не зависящий от языка. JSON используется для обмена данными между приложениями, написанными на любом языке программирования.

JSON-объект - это отдельный объект, который содержит две функции, parse и stringify, которые используются для анализа и построения текстов JSON.

  • JSON.stringify создает строку, соответствующую следующей грамматике JSON.
  • JSON.parse принимает строку, соответствующую грамматике JSON.

Метод parseJSON будет включен в Fourth Edition of ECMAScript. В то же время, реализация JavaScript доступна на json.org.

var objLiteral = {foo: 42}; // JavaScript Object
console.log('Object Literal : ', objLiteral ); // Object {foo: 42}foo: 42__proto__: Object

// This is a JSON String, like what you'd get back from an AJAX request.
var jsonString = '{"foo": 452}';
console.log('JOSN String : ', jsonString ); // {"foo": 452}

// This is how you deserialize that JSON String into an Object.
var serverResposnceObject = JSON.parse( jsonString );
console.log('Converting Ajax response to JavaScript Object : ', serverResposnceObject); // Object {foo: 42}foo: 42 __proto__: Object

// And this is how you serialize an Object into a JSON String.
var serverRequestJSON = JSON.stringify( objLiteral );
console.log('Reqesting server with JSON Data : ', serverRequestJSON); // '{"foo": 452}'

JSON является подмножеством JavaScript. Javascript был получен из стандарта языка программирования ECMAScript.


► ECMAScript

ECMAScript стал одним из самых широко используемых в мире языков программирования общего назначения. Он наиболее известен как язык, встроенный в веб-браузеры, но также широко применяется для серверных и встроенных приложений. ECMAScript основан на нескольких исходных технологиях, наиболее известными из которых являются JavaScript(Netscape Communications) и JScriptMicrosoft Corporation.) .Хотя до 1994 года ECMA была известна как «Европейская ассоциация производителей компьютеров», после 1994 года, когда организация стала глобальной, «торговая марка» «Ecma» сохранилась по историческим причинам.

ECMAScript - это язык, тогда как JavaScript, JScript и даже ActionScript называются "Dialects".

Диалекты были получены из того же языка. Они очень похожи друг на друга, поскольку они произошли от одного языка, но они претерпели некоторые изменения. Диалект - это разновидность самого языка. Это происходит от одного языка.

  • Язык SQL - Hibernate MySQL Dialect, Oracle Dialect, ... с некоторыми изменениями или добавленной функциональностью.

Информация о браузере и компьютере ваших пользователей.

navigator.appName // "Netscape"

ECMAScript - это язык сценариев, который лежит в основе JavaScript. ,JavaScript language resources

ECMA-262 Links
Initial Edition, June 1997 PDF.
2nd Edition, August 1998 PDF.
3rd Edition, December 1999 PDF.
5th Edition, December 2009 PDF.
5.1 Edition, June 2011 HTML.
6th Edition, June 2015 HTML.
7ᵗʰ Edition, June 2016 HTML.
8th edition, June 2017 HTML.
9th Edition, 2018 HTML.

ПРИМЕЧАНИЕ « 4-е издание ECMAScript не опубликовано, так как работа была неполной .


JSON определяет небольшой набор правил форматирования для переносимого представления структурированных данных.

  1. ► Значения ключей должны быть в кавычках, для ключей допускаются только строки. Если вы используете не String, он будет преобразован в String. Но не рекомендуется использовать ключи, отличные от String. Проверьте пример как это - { 'key':'val' }болееRFC 4627 - jsonformatter

    var storage = {
      0 : null,
      1 : "Hello"
    };
    console.log( storage[1] ); // Hello
    console.log( JSON.stringify( storage ) ); // {"0":null,"1":"Hello","2":"world!"}
    
    var objLiteral = {'key1':'val1'};
        var arr = [10, 20], arr2 = [ 'Yash', 'Sam' ];
        var obj = { k: 'v' }, obj2 = { k2: 'v2' };
        var fun = function keyFun() {} ;
    
    objLiteral[ arr ] = 'ArrayVal';     objLiteral[ arr2 ] = 'OverridenArrayVal';
    objLiteral[ obj ] = 'ObjectVal';    objLiteral[ obj2 ] = 'OverridenObjectVal';
    objLiteral[ fun ] = 'FunctionVal';
    
    console.log( objLiteral );
    // Object {key1: "val1", 10,20: "ArrayVal", Yash,Sam: "OverridenArrayVal", [object Object]: "OverridenObjectVal", function keyFun() {}: "FunctionVal"}
    console.log( JSON.stringify( objLiteral ) );
    // {"key1":"val1","10,20":"ArrayVal","Yash,Sam":"OverridenArrayVal","[object Object]":"OverridenObjectVal","function keyFun() {}":"FunctionVal"}
    console.log( JSON.parse( JSON.stringify( objLiteral ) ) );
    // Object {key1: "val1", 10,20: "ArrayVal", Yash,Sam: "OverridenArrayVal", [object Object]: "OverridenObjectVal", function keyFun() {}: "FunctionVal"}
    
    console.log('Accessing Array  Val : ', objLiteral[ [10,20] ] );
    console.log('Accessing Object Val : ', objLiteral[ '[object Object]' ] );
    console.log('Accessing Function Val : ', objLiteral[ 'function keyFun() {}' ] );
  2. ► Строки JSON должны заключаться в кавычки "а не". Строка очень похожа на строку C или Java. Строки должны быть заключены в двойные кавычки.

    • Литералы - это фиксированные значения, а не переменные, которые вы буквально предоставляете в своем скрипте.
    • Строка - это последовательность из нуля или более символов, заключенная в кавычки с обратной косой чертой, то же самое обозначение используется в большинстве языков программирования.
      • Special - Специальные символы разрешены в строке, но не рекомендуется использовать.
      • \ "- Специальные символы могут быть экранированы. Но не рекомендуется экранировать (') Одинарные кавычки. В строгом режиме он выбрасывает и ошибка - SyntaxError: Unexpected token ' in JSON

    Проверьте с помощью этого кода { "Hai\" \n Team 🔫":5, "Bye \'": 7 }через онлайн JSON Edtions.ModesnotStrict,Strinct.

    var jsonString = "{'foo': 452}"; // {'foo': 452}
    var jsonStr = '{"foo": 452}'; // {"foo": 452}
    
    JSON.parse( jsonString ); // Unexpected token ' in JSON at position 1(…)
    JSON.parse( jsonStr ); // Object {foo: 452}
    
    objLiteral['key'] = 'val'; // Object {foo: 42, key: "val"}
    objLiteral.key2 = 'val';
    
    // objLiteral.key\n3 - SyntaxError: Invalid or unexpected token
    objLiteral['key\n3'] = 'val'; // Object {"foo": "42", key: "val", key2: "val", "key↵3": "val"}
    
    JSON.stringify( objLiteral ); // {"foo":"42","key":"val","key2":"val","key\n3":"val"}

Объект аксессоры собственности обеспечивают доступ к свойствам объекта с помощью точечной нотации или брекета обозначения.

  1. ► У вас есть более ограниченный диапазон значений (например, функции не допускаются). Значение может быть строкой в ​​двойных кавычках, числом, логическим значением, нулем, объектом или массивом. Эти структуры могут быть вложенными.

    var objLiteral = {};
    objLiteral.funKey = function sayHello() {
        console.log('Object Key with function as value - Its outcome message.');
    };
    
    objLiteral['Key'] = 'Val';
    
    console.log('Object Literal Fun : ', objLiteral );
    // Object Literal Fun :  Object {Key: "Val"}Key: "Val"funKey: sayHello()__proto__: Object
    console.log( JSON.stringify( objLiteral ) ); // {"Key":"Val"}

введите описание изображения здесь


JavaScriptявляется наиболее популярной реализацией стандарта ECMAScript. Основные функции Javascript основаны на стандарте ECMAScript, но Javascript также имеет другие дополнительные функции, которых нет в спецификации / стандарте ECMA. У каждого браузера есть интерпретатор JavaScript.

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

Literals :

'37' - 7    // 30
'37' + 7    // "377"
+'37' + 7   // 44
+'37'       // 37
'37'        // "37"

parseInt('37');     // 37
parseInt('3.7');    // 3

parseFloat(3.7);    // 3.7

// An alternative method of retrieving a number from a string is with the + (unary plus) operator:
+'3.7'              // 3.7

Object literals RFC 7159

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

ECMAScript поддерживает наследование на основе прототипов. Каждый конструктор имеет связанный прототип, и каждый объект, созданный этим конструктором, имеет неявную ссылку на прототип (называемый прототипом объекта), связанный с его конструктором. Кроме того, прототип может иметь ненулевую неявную ссылку на свой прототип и т. Д .; это называется прототипом цепи.

В объектно-ориентированном языке на основе классов в общем случае состояние передается экземплярами, методы - классами, а наследование имеет только структуру и поведение. В ECMAScript состояние и методы переносятся объектами, а структура, поведение и состояние наследуются.

Прототип - это объект, используемый для реализации наследования структуры, состояния и поведения в ECMAScript. Когда конструктор создает объект, этот объект неявно ссылается на связанный с конструктором прототип с целью разрешения ссылок на свойства. На связанный с прототипом конструктор может ссылаться выражение программы constructor.prototype, а свойства, добавленные в прототип объекта, передаются по наследству всем объектам, совместно использующим прототип.

Яши
источник
2

Для тех, кто все еще думает, что RFC важнее, чем блоги и заблуждения, основанные на мнениях, давайте попробуем ответить на некоторые вопросы. Я не собираюсь повторять все правильные различия, уже упомянутые в предыдущих ответах, здесь я просто пытаюсь добавить ценность, суммируя некоторые важные части rfc7159

Выдержки из https://tools.ietf.org/html/rfc7159

  1. JavaScript Object Notation (JSON) - это текстовый формат для сериализации структурированных данных. Он получен из объектных литералов JavaScript, как определено в стандарте языка программирования ECMAScript, третье издание [ECMA-262].
  2. JSON может представлять четыре примитивных типа (строки, числа, логические значения и нуль) и два структурированных типа ( объекты и массивы).
  3. Объект представляет собой неупорядоченный набор из нуля или более пар имя / значение, где имя представляет собой строку и значение является строка, число, логическое значение, нулевой объект , или массив.
  4. begin-object = ws% x7B ws; {левая фигурная скобка
  5. конечный объект = ws% x7D ws; } правая фигурная скобка
  6. Значение JSON ДОЛЖНО быть объектом , массивом, числом или строкой или одним из следующих трех литеральных имен: false null true
  7. Объект структура представлена в виде пары фигурных скобок
  8. Имена внутри объекта ДОЛЖНЫ быть уникальными. объект = начало-объект [член * (элемент-разделитель значений)] конечный объект
  9. Объект , чьи имена являются уникальным совместит в том смысле , что все программные реализации , получающие этот объект будут согласовывать отображения имени-значение. Когда имена внутри объекта не являются уникальными, поведение программного обеспечения, получающего такой объект , непредсказуемо.
  10. Примеры (со страницы 12 RFC)

    Это объект JSON:

          {
            "Image": {
                "Width":  800,
                "Height": 600,
                "Title":  "View from 15th Floor",
                "Thumbnail": {
                    "Url":    "http://www.example.com/image/481989943",
                    "Height": 125,
                    "Width":  100
                },
                "Animated" : false,
                "IDs": [116, 943, 234, 38793]
              }
          }

    Его член Image является объектом, чей элемент Thumbnail является объектом, а член ID является массивом чисел.

На самом деле не существует такого понятия, как «объект JSON».

В самом деле?

Даниэль Д.
источник
1
Дави, это не так Object, это String. Спасибо
абу абу
1

Насколько я понимаю, главное отличие - это гибкость .

JSON - это своего рода оболочка для «JavaScript Object Notation», которая заставляет пользователей подчиняться более строгим правилам определения объектов. И это достигается путем ограничения возможных способов объявления объектов, предоставляемых функцией JavaScript Object Notation.

В результате мы имеем более простые и стандартизированные объекты, которые лучше подходят для обмена данными между платформами.

Таким образом, по сути, newObject в моем примере выше - это объект, определенный с помощью JavaScript Objeect Notation; но это не «действительный» объект JSON, потому что он не следует правилам, требуемым стандартами JSON.

Эта ссылка также весьма полезна: http://msdn.microsoft.com/en-us/library/bb299886.aspx

pencilCake
источник
2
Смысл JSON и объектной нотации совершенно различен: первый используется только для обмена данными, а второй - для создания объектов JS только для внутреннего использования. Это не более и менее строгие версии одного и того же.
ilyo
0

Сначала вы должны знать, что такое JSON:

Это независимый от языка формат обмена данными. Синтаксис JSON был основан на нотации JavaScript Object Literal, но между ними есть различия.

Например, в JSON все ключи должны быть заключены в кавычки, а в объектных литералах это необязательно:

// JSON: {"foo": "bar"}

// Литерал объекта: var o = {foo: "bar"}; Кавычки обязательны для JSON, потому что в JavaScript (точнее в ECMAScript 3rd. Edition) использование зарезервированных слов в качестве имен свойств запрещено, например:

var o = {if: "foo"}; // SyntaxError в ES3 Хотя использование строкового литерала в качестве имени свойства (цитирование имени свойства) не вызывает проблем:

var o = {"if": "foo"}; Так что для «совместимости» (и, может быть, легко оценивать?) Кавычки обязательны.

Типы данных в JSON также ограничены следующими значениями:

строковый номер объектный массив Литерал как: true false null Грамматика строк изменяется. Они должны быть разделены двойными кавычками, в то время как в JavaScript вы можете использовать одинарные или двойные кавычки взаимозаменяемо.

// Неверный JSON: {"foo": 'bar'} Также меняется и принятая грамматика чисел JSON, в JavaScript вы можете использовать шестнадцатеричные литералы, например, 0xFF, или (печально известные) восьмизначные литералы, например, 010. В JSON вы можете использовать только десятичные литералы.

// Неверный JSON: {"foo": 0xFF}

Рази Сайед 'Абди'
источник
0

Javascript Object Literal против JSON:

  • Синтаксис литерала объекта - очень удобный способ создания объектов JavaScript
  • JSONЯзык, который означает «объектов JavaScript», имеет свой синтаксис , полученный из объектов JavaScript буквального синтаксиса. Он используется как независимый от языка программирования формат текстовой передачи данных.

Пример:

Обозначение объектов JS, используемое в JS для удобного создания объектов в коде:

const JS_Object = {
  1: 2,  // the key here is the number 1, the value is the number 2
  a: 'b', // the key is the string a, the value is the string b
  func: function () { console.log('hi') }
  // the key is func, the value is the function
}

Пример JSON:

{"widget": {
    "debug": "on",
    "window": {
        "title": "Sample Konfabulator Widget",
        "name": "main_window",
        "width": 500,
        "height": 500
    },
    "image": { 
        "src": "Images/Sun.png",
        "name": "sun1",
        "hOffset": 250,
        "vOffset": 250,
        "alignment": "center"
    },
    "text": {
        "data": "Click Here",
        "size": 36,
        "style": "bold",
        "name": "text1",
        "hOffset": 250,
        "vOffset": 100,
        "alignment": "center",
        "onMouseUp": "sun1.opacity = (sun1.opacity / 100) * 90;"
    }
}}

Основные отличия:

  • Все ключи объекта в JSON должны быть строками. В Javascript объектными ключами могут быть строки или числа

  • Все строки в JSON должны быть заключены в "двойные кавычки". В то время как в Javascript допускаются как одинарные, так и двойные кавычки. Даже без кавычек в нотации объекта Javascript ключи объекта неявно преобразуются в строки.

  • В JSON функция не может быть определена как значение объекта (поскольку это зависит от Javascript). В Javascript это полностью законно.

Javascript встроить в JSONобъект:

JSONобъекты могут быть легко преобразованы в Javascript и наоборот, используя встроенный JSONобъект, который Javascript предлагает во время выполнения. Например:

const Object = {
  property1: true,
  property2: false,
}; // creating object with JS object literal syntax

const JSON_object = JSON.stringify(Object);  // stringify JS object to a JSON string

console.log(JSON_object); // note that the (string) keys are in double quotes

const JS_object = JSON.parse(JSON_object);  // parse JSON string to JS object

console.log(JS_object.property1, JS_object.property2); 
// accessing keys of the newly created object

Виллем ван дер Веен
источник
0

Вот одно удивительное отличие: вы не можете использовать undefinedв json, и все поля объекта с неопределенными значениями исчезнут послеJSON.stringify

let object =  { "a": undefined } ;

let badJSON= '{ "a": undefined }';


console.log('valid JS object :', object );
console.log('JSON from object:', JSON.stringify(object) );
console.log('invalid json    :', JSON.parse(badJSON) );

🙈🙉🙊

Камил Келчевски
источник