JSONでは、それぞれの名前が引用されているのはなぜですか?


91

JSON仕様では、JSONはオブジェクトまたは配列であると規定されています。オブジェクトの場合、

オブジェクト構造は、0個以上の名前と値のペア(またはメンバー)を囲む中括弧のペアとして表されます。 名前は文字列です。 ...

そして後で、仕様は文字列が引用符で囲まれていると述べています。

どうして?

したがって、

{"Property1":"Value1","Property2":18}

ではなく

{Property1:"Value1",Property2:18}

質問1:名前と値のペアの名前を引用符で囲まない識別子にしないでください。


質問2:Javascriptで評価した場合、上記の2つの表現に意味上の違いはありますか?


1
@Bruno:あなたは、XMLの同じように話すことができ...と悲しいことに、そこにいくつかはよく...プログラミング言語として使用するXMLにしようとすることができる
マイクDeSimoneさん

2
+1 ...それは独特の矛盾のように見えます.... "引用符付き"は標準のJSONになりますが、動作しませんeval()(つまり、JavaScript)。
skaffman、2010年

2
@bruno、いいえ。展開すると、「JavaScript Object Notation」になります。これは問題ありません
Dave Archer

2
@skaffman — JavaScriptで評価されたときに機能します。
Quentin

1
@Bruno-JSONはデータ形式です。「JSONで」とは、仕様に従ってフォーマットされたデータを意味します。
Cheeso 2010年

回答:


57

質問1:名前と値のペアの名前を引用符で囲まない識別子にしないでください。

JSONの設計哲学は「シンプルに保つ」です

「と引用名"よりもずっと簡単であるあなたがして名前を引用する」"または'しかしあなたがする必要はありません、彼らは(それのキーワードになるだろうか、文字の組み合わせ)特定の文字が含まれていない限り'または"依存引用符で囲む必要があるかもしれません区切り文字何であなたは」選択しました

質問2:JavaScriptで評価した場合、上記の2つの表現に意味上の違いはありますか?

いいえ。JavaScriptでは、これらは同じです。


3
いいえ、それは正しくありません。CMSが正解です。この答えは、本当の理由のいい副作用です。説明が簡単になるだけでなく、パーサーの記述も簡単になります。これは、識別子の文字列の解析ルールを再利用できるためです。
ブルトン語

それとは別に、識別子がたまたま予約語である場合、識別子ではなくその単語として解釈されるという点で、わずかな意味上の違いがあります。
ブルトン語

2
CMSの答えを+1してください、それは正しいです。二重引用符はコード規則ではありませんが、オブジェクトのキーとして予約語を使用したくない場合。例:{property1: "abc"、this: "def"} is WRONG(this is a reserved keyword)
Sorin Mocanu

質問2:Javascriptの差が小さい使用してJSON.parse機能を:JSON.parse('{"a":1}') うまく機能する理由、JSON.parse('{a:1}')します例外を発生させます
nhnghia

@nhnghia —質問2は、ソースコード JSONではなくJavaScriptとして評価することです。JSON.parseJavaScriptで実装されたJSONパーサーであり、JavaScriptパーサーではありません。
クエンティン

134

私は、Douglas Crockford(JSON標準の作成者)がYahooに提供したプレゼンテーションからの引用を残します。

彼はどのようにして JSON を発見したか、特に引用符付きのキーを使用することにした理由について話します

....引用符で囲まれていない名前の問題を発見したのはそのときです。ECMA Script 3には、気まぐれな予約語ポリシーがあることがわかりました。予約語はキー位置に引用符で囲む必要がありますが、これは実際には厄介です。これを標準に定式化するとき、すべての予約語を標準に入れる必要はありませんでした。

当時、私は人々を説得しようとしていました。ええ、JavaScriptでアプリケーションを書くことができます。それは実際に機能し、優れた言語です。それと同時に、私は言いたくありませんでした。そして、彼らがしたこの本当に愚かなことを見てください!代わりに、キーを引用することにしました。
そうすれば、私たちはそれがいかに強打であるかについて誰かに話す必要はありません。

そのため、今日まで、キーはJSONで引用されています。

あなたはここで完全なビデオとトランスクリプトを見つけることができます


うーん... JSON標準の作成者?!それは言い過ぎだと思います。JSONはJavaScript Object Notationであり、JavaScript(ECMA)仕様に基づいています。
Sorin Mocanu 2010年

42
@ソリン:JSONとJavaScriptオブジェクトリテラルを混同しないでください。JSONは、言語にとらわれないデータ交換フォーマットであり、2006年にCrockfordによって提案されました(tools.ietf.org/html/rfc4627)。その文法は、JavaScriptオブジェクトリテラル(bclary.com/2004/11/07/#a-11.1とは異なります。0.5)、基本的にのみ可能にすることによって、文字列のキーと値がしなければならないことオブジェクト配列数値文字列、または下記リテラル名のいずれかヌル 。JavaScriptのオブジェクトリテラルは、識別子、としてキーを持つことができ文字列リテラル、または数値リテラル式に、および値には任意のタイプを指定できます...
CMS

@CMSそして今日のJavaScriptは、オブジェクトコンストラクタ式内での省略形の識別子を許可します。例:{ a }、ここで、プロパティ 'a'はグローバルまたはローカル変数 'a'の値をコピーします。
Hydroper

@CMSそして計算されたキーもあります:{[key]: value}
Hydroper

0

:識別子には空白と空白の両方を使用できます。引用符がないと、何が識別子を正確に構成しているかを判断しようとするときに曖昧さが生じます。


0

JavaScriptオブジェクトでは、キーペアを含むハッシュ/ハッシュテーブルのようにオブジェクトを使用できます。

ただし、キーにjavascriptが名前としてトークン化できない文字が含まれている場合、キーではなくオブジェクトのプロパティのようにアクセスしようとすると失敗します。

var test  = {};
test["key"] = 1;
test["#my-div"] = "<div> stuff </div>";

// test = { "key": 1, "#my-div": "<div> stuff </div>" };

console.log(test.key);           // should be 1
console.log(test["key"]);        // should be 1
console.log(test["#my-div"]);    // should be "<div> stuff </div>";
console.log(test.#my-div);       // would not work.

識別子には、JavaScriptのトークン/識別子として評価できない文字が含まれる場合があるため、一貫性を保つためにすべての識別子を文字列に入れるのが最善です。


-2

Cheesoの質問に対する正しい答えは、実装がドキュメントを上回ったということです。それはもはやキーとして文字列を必要とせず、文字列(つまり引用符で囲まれたもの)または(おそらく)変数名として使用できるあらゆるものである可能性がある何かです。 、または$で、文字、数字、および$と_のみが含まれます。

私が行ったのと同じ考えでこの質問にアクセスする次の人のために残りを簡素化したいと思いました。ここに肉があります:

変数名は、オブジェクトキーとして使用するとJSONで補間されません(Friedoに感謝します)

ブルトンは、「キー」の代わりに「識別子」を使用して、「識別子がたまたま予約語である場合、識別子ではなくその単語として解釈される」と書いている。これは本当かもしれませんが、私は問題なくそれを試しました:

var a = {do:1,long:2,super:3,abstract:4,var:5,break:6,boolean:7};
a.break

=> 6

引用符の使用について、クエンティンは「...しかし、[キー]に特定の文字(またはキーワードになる文字の組み合わせ)が含まれていない限り、必要はありません」と書いています。

@記号を使用して、前の部分(特定の文字)が正しいことを発見しました(実際、$と_だけがエラーを引き起こさない文字だと思います)。

var a = {a@b:1};

=>構文エラー

var a = {"a@b":1};
a['a@b']

=> 1

しかし、上記で示したように、キーワードに関する括弧は正しくありません。

冒頭の{とコロンの間、または後続のプロパティのカンマとコロンの間のテキストが、引用符で囲まれていない文字列として使用され、オブジェクトキーを作成するか、Friedoが言うように、そこに変数名がないため、 t補間されます:

var uid = getUID();
var token = getToken();            // Returns ABC123
var data = {uid:uid,token:token};
data.token

=> ABC123


-3

jsonがオブジェクトを記述する場合、実際には次のようになります

var foo = {};

var bar = 1;

foo["bar"] = "hello";
foo[bar] = "goodbye";

それで、

foo.bar == "hello";
foo[1] == "goodbye" // in setting it used the value of var bar

したがって、例で同じ結果が得られたとしても、「生のコード」での同等の結果は得られません。多分それが理由ですか?知らない、ただのアイデア。


3
@David、変数名は、オブジェクトキーとして使用した場合、JSで補間されません。{ bar: 'goodbye' }キー名をの値に設定するのではなく、bar単に値を設定しますbar。他は仕様が引用を必要とする理由について正しいです:それはキーワードと特殊文字の衝突を避けるためです。
フリード

-3

名前の引用が必要な場合にのみ許可されている場合は、データサイズが減少する可能性があります

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.