次のように、JSON データの周りに括弧を追加する必要があることを (難しい方法で) 学びました。
stuff = eval('(' + data_from_the_wire + ')');
// where data_from_the_wire was, for example {"text": "hello"}
(少なくとも Firefox 3 では)。
この背後にある理由は何ですか? ボンネットの背後にあるものを理解せずにコードを書くのは嫌いです。
次のように、JSON データの周りに括弧を追加する必要があることを (難しい方法で) 学びました。
stuff = eval('(' + data_from_the_wire + ')');
// where data_from_the_wire was, for example {"text": "hello"}
(少なくとも Firefox 3 では)。
この背後にある理由は何ですか? ボンネットの背後にあるものを理解せずにコードを書くのは嫌いです。
eval
一連の Javascript ステートメントを受け入れます。Javascript パーサーは、ステートメント内で発生する '{' トークンを、オブジェクト リテラルの開始ではなく、ブロックの開始として解釈します。
次のようにリテラルを括弧で囲むと({ data_from_the_wire })
、Javascript パーサーが式解析モードに切り替わります。式内のトークン '{'は、ブロックではなくオブジェクト リテラル宣言の開始を意味するため、Javascript はそれをオブジェクト リテラルとして受け入れます。
括弧data_from_the_wire
を入れることは、事実上次と同等です
stuff = eval('return ' + data_from_the_wire + ';');
括弧なしで eval すると、コードが評価され、その中に名前付き関数がある場合、それらは定義されますが、返されません。
例として、関数を作成した直後に呼び出す機能を取り上げます。
(function() { alert('whoot'); })()
定義したばかりの関数を呼び出します。ただし、次の場合は機能しません。
function() { alert('whoot'); }()
したがって、括弧はコードを実行するコードだけでなく、返される式に効果的に変換することがわかります。
理由はわかりませんが、 json.orgの JSON クラスを使用して JSON を解析しています。eval を使用するよりもはるかに安全です。
JavaScriptでは、中括弧を使用してブロックステートメントを作成します。
{
var foo = "bar";
var blah = "baz";
doSomething();
}
上記の行は文字列の中に入れてeval
問題なく使用できます。今これを考慮してください:
{
"foo": "bar",
"blah": "baz"
}
中括弧を使用すると、JavaScriptエンジンはそれをグループ式と見なすため、:
文字の周りの構文エラーが発生します。MDNからの引用...JavaScriptガイド...オブジェクトリテラル:
ステートメントの先頭でオブジェクトリテラルを使用しないでください。{はブロックの先頭として解釈されるため、これによりエラーが発生したり、期待どおりに動作しなくなったりします。
オブジェクトリテラルを内部にラップする回避策は、()
その内容をブロックステートメントとしてではなく式として扱うようにエンジンに指示することで機能します。したがって、これは機能しません。
({
var foo = "bar";
var blah = "baz";
doSomething(evil);
})
// parse error
しかし、これはします:
({
"foo": "bar",
"blah": "baz"
})
// returns object
これは、丸括弧がないと、JavaScriptがラベル{"text": ...
として解釈しようとして失敗するために発生します。コンソールで試してみると、「無効なラベル」エラーが表示されます。
data_from_the_wire
実際には、の値によって異なります。ほとんどの場合、構文は問題ありませんが、で始まる行{
はラベルとして解析され、あなたの構文は無効です。括弧で囲むと、パーサーが式を誤って解釈するのを防ぎます。
本当に解析の問題です。文字列、数値、または関数を使用すれば、その問題は発生しません。
1つの解決策は、式ではなく、常に命令を評価することです。あなたは書ける
eval('var stuff = {"text": "hello"}');
わかりませんが、実際にはこれに対する答えに興味がありますが、括弧がないと、データはdata_from_the_wire
クロージャーとして解釈されると思います。おそらく括弧が評価を強制するため、連想配列が「返されます」。
ただし、これは反対票につながる一種の推測です =)。
編集
Douglas Crockford は、彼のJSONサイトで構文のあいまいさについて言及していますが、それはあまり役に立ちませんでした。