244

Object Literal Notationを使用して定義された JavaScript オブジェクトとJSON オブジェクトの主な違いは何ですか?

JavaScript の本によると、これはObject Notationを使用して定義されたオブジェクトであると書かれています。

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

この場合、JSON オブジェクトではないのはなぜですか? 引用符を使用して定義されていないという理由だけですか?

4

10 に答える 10

278

最初にJSONが実際に何であるかを明確にしましょう。JSON は、XML、CSV、または YAML によく似た、言語に依存しないテキスト形式のデータ交換形式です。

データはさまざまな方法で保存できますが、テキスト ファイルに保存してコンピューターで読み取り可能にする場合は、何らかの構造に従う必要があります。JSON は、このような構造を定義する多くの形式の 1 つです。

このような形式は通常、言語に依存しません。つまり、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 以降、キーも計算できるようになり、さらに別の構文が導入されました)。
  • 値は、関数定義やundefined.
  • 重複キーは、定義済みの指定された結果を生成します (ルース モードでは、後者の定義が前者を置き換えます。厳密モードでは、エラーになります)。

構文を見るだけでわかるように、次の 2 つの理由により、例は 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 ソース コードを書いていて、stringを扱っていない場合は、JSON を扱っていません。データを JSON として (たとえば、ajax やファイルからの読み取りを介して) 受け取ったかもしれませんが、ユーザーまたは使用しているライブラリがそれを解析すると、それはもう JSON ではありません。


オブジェクト リテラルと JSON がているという理由だけで、それらを同じ名前にできるわけではありません。「JSON オブジェクト」などというものはありませんも参照してください。

于 2010-05-25T11:42:45.097 に答える
47

JSONには、次のような非常に制限された構文があります。

  • キー値は引用符で囲む必要があります
  • 文字列は引用符で囲む必要があります"'
  • 値の範囲がより制限されている (たとえば、関数が許可されていない)
于 2010-05-25T11:45:03.230 に答える
17

「JSONオブジェクト」のようなものは実際にはありません。

JSON 仕様は、データを文字列としてエンコードするための構文です。人々が「JSON オブジェクト」( javascript で) と呼んでいるものは、(おそらく) 有効な JSON 文字列から逆シリアル化された通常の JavaScript オブジェクトであり、有効な JSON 文字列として簡単に再シリアル化できます。これは通常、データのみが含まれている (関数は含まれていない) ことを意味します。また、JSON には日付型がないため、日付がないことも意味します (おそらく JSON で最も厄介なことです;)

さらに、(余談ですが...) 人々が「JSON オブジェクト」について話すとき、ほとんどの場合、最上位に「中かっこ」があるデータを意味します。これは、javascript オブジェクトにうまく対応しています。ただし、JSON 仕様では、JSON 文字列の最上位に単一の「中かっこ」オブジェクトが存在する必要はありません。最上位にリストを持つこと、または単一の値を持つことさえも、完全に有効な JSON です。したがって、すべての「JSON オブジェクト」は有効な JSON に対応しますが、すべての有効な JSON 文字列が「JSON オブジェクト」と呼ばれるものに対応するわけではありません! (文字列はリストまたは原子値を表す可能性があるため)

于 2011-12-14T15:55:07.423 に答える
9

JavaScript の JSON によると、

JSON は、JavaScript のオブジェクト リテラル表記のサブセットです。

つまり、有効な JSON は有効な JavaScript オブジェクト リテラル表記でもありますが、必ずしもその逆であるとは限りません。

ドキュメントを読むことに加えて、@Filix King が提案したように、JSONLint オンライン JSON バリデーターを試してみることもお勧めします。これが、JSON オブジェクトのキーが文字列でなければならないことを学んだ方法です。

于 2011-02-16T03:13:05.703 に答える
1

私が理解している限り、主な違いは柔軟性です。

JSONは、「JavaScript Object Notation」の一種のラッパーであり、ユーザーはオブジェクトを定義するためのより厳格なルールに従う必要があります。そして、JavaScriptObjectNotation機能によって提供される可能なオブジェクト宣言方法を制限することによってこれを行います。

その結果、プラットフォーム間のデータ交換に適した、よりシンプルで標準化されたオブジェクトができました。

したがって、基本的に、上記の例のnewObjectは、JavaScriptObjeectNotationを使用して定義されたオブジェクトです。ただし、JSON標準で要求されるルールに準拠していないため、「有効な」JSONオブジェクトではありません。

このリンクも非常に役立ちます:http: //msdn.microsoft.com/en-us/library/bb299886.aspx

于 2010-05-25T12:06:14.883 に答える
1

ブログや意見に基づく誤解よりも RFC の方が重要だといまだに考えている人のために、いくつかの点を明確にして答えてみましょう。以前の回答で既に述べたすべての正しい違いを繰り返すつもりはありません。ここでは、いくつかの重要な部分を要約して値を追加しようとしています rfc7159

https://www.rfc-editor.org/rfc/rfc7159からの抜粋

  1. JavaScript Object Notation (JSON) は、構造化データをシリアル化するためのテキスト形式です。 これは、ECMAScript プログラミング言語標準、第 3 版 [ECMA-262] で定義されているように、JavaScriptのオブジェクトリテラルから派生しています。

  2. JSON は、4 つのプリミティブ型 (文字列、数値、ブール値、および null) と 2 つの構造化型 (オブジェクトと配列) を表すことができます。

  3. オブジェクトは、0 個以上の名前と値のペアの順序付けされていないコレクションです。名前は文字列で、値は文字列、数値、ブール値、null、object または配列です。

  4. 開始オブジェクト = ws %x7B ws ; { 左中括弧

  5. end-object = ws %x7D ws ; 右中括弧

  6. JSON 値は、オブジェクト、配列、数値、文字列、または次の 3 つのリテラル名のいずれかでなければなりません: false null tr​​ue

  7. オブジェクト構造は、中かっこのペアとして表されます

  8. オブジェクト内の名前は一意である必要があります。 object = begin-object [ member *( value-separator member ) ] end-object

  9. 名前がすべて一意であるオブジェクトは、そのオブジェクトを受け取るすべてのソフトウェア実装が名前と値のマッピングに同意するという意味で相互運用可能ですオブジェクト内の名前が一意でない場合、そのようなオブジェクトを受け取るソフトウェアの動作は予測できません。

  10. 例 (RFC の 12 ページから)

    これは 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 メンバーがオブジェクトであり、IDs メンバーが数値の配列であるオブジェクトです。

「JSONオブジェクト」のようなものは実際にはありません。

本当に?

于 2016-08-10T12:44:45.600 に答える
0

ここに 1 つの驚くべき違いがあります: json では使用できずundefined、未定義の値を持つすべてのオブジェクト フィールドは後で消えます。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) );

于 2019-06-19T18:18:06.077 に答える