2009-06-08 13 views
33

私が学んだ私はこのように、JSONデータの周りに括弧を追加する必要があります(難しい方法): JSONデータを評価するためにJavaScriptの評価に括弧が必要なのはなぜですか?

stuff = eval('(' + data_from_the_wire + ')'); 
// where data_from_the_wire was, for example {"text": "hello"} 

(Firefox 3の、少なくとも)。

この理由は何ですか?私はフードの後ろに何があるのか​​理解せずにコードを書くのが嫌いです。

+1

私はあなたが「(」と「)」英語のネイティブスピーカーではなく、見括弧です。あなたがこれを訂正すれば、他の人があなたの投稿を見つけるのに役立つかもしれません。 –

答えて

38

stuff = eval('return ' + data_from_the_wire + ';'); 

を効果的に等価であるあなたは、括弧なしでevalにした場合、コードが評価されるだろう、とあなたはそれそれらの内部の任意の名前の機能を持っていた場合に定義されるだろうしかし、返されません。今定義された関数を呼び出します

(function() { alert('whoot'); })() 

は、一例として、それは漢が作成されて同じように関数を呼び出す能力を取ります。以下では、しかし、動作しません:

function() { alert('whoot'); }() 

だから我々は括弧が効果的にそして実行するというだけのコードよりも、返す式にコードを入れていることがわかります。

+3

+1非常に明確な説明。ありがとう。 –

+1

オリバーと同じ理由で+1: – Stefan

+4

最初の部分は正確には正しくありません。 evalはその文字列をトップレベルのコードとして解釈するため、returnは機能しません。 関数の問題は、元の質問と似ています。なぜなら、関数*の文と関数*式*のあいまいさが原因です(karim79の解答を見てください)。 –

-2

私は実際にこれに対する答えに興味がありますが、私の推測によれば、かっこがなければdata_from_the_wireのデータはクロージャーとして解釈されます。多分括弧が評価を強制し、連想配列が '返されます'。

これは、=)の下降音につながる推測のようなものです。

EDIT

ダグラス・クロックフォードは彼のJSONサイト上の構文の曖昧さを言及したが、それは本当に私を助けていませんでした。

10

理由はわかりませんが、the JSON classからjson.orgを使用してJSONを解析します。 evalを使うよりもはるかに安全です。

+5

なぜdownvote? これは有効な回答のようです。 evalを使用するのは安全ではありません。 –

+0

彼はJSONを解析するためにevalを適切に使用する方法を尋ねていませんが、かっこが必要な理由を尋ねています。 –

+2

@TimČas私は直接質問に答えていないことに気がつきましたが、誰かが足で銃を指して、なぜ安全を取り除く必要があるのか​​尋ねるとき、私はまず銃をあなたの足元に向けるのは良い考えではないかもしれません。 –

62

evalは、一連のJavascript文を受け入れます。 Javascriptパーサー は、ステートメント内でブロックの開始として発生し、オブジェクトリテラルの開始ではなく、 '{'トークンを解釈します。

リテラルを次のようにカッコで囲むと、({ data_from_the_wire }) は、式解析モードに切り替わります。式の中のトークン '{'はオブジェクトリテラル宣言の開始を意味し、はブロックではないため、Javascriptはそれをオブジェクトリテラルとして受け入れます。 data_from_the_wireの周りに括弧を置く

2

ラウンドブレースなしでは、JavaScriptは{"text": ...a labelと解釈して失敗し、失敗します。コンソールで試してみると「無効なラベル」というエラーが表示されます。

1

実際にはdata_from_the_wireという値に依存します。ほとんどの場合、構文は正常ですが、{で始まる行はラベルとして解析され、あなたは無効です。それをかっこで囲むと、パーサがあなたの表現を誤って解釈するのを防ぎます。

本当に解析の問題です。文字列、数字または関数を使用すると、そのような問題は発生しません。

解決策の1つは、常にeval命令であり、式ではありません。あなたはJavaScriptで

eval('var stuff = {"text": "hello"}'); 
9

を書くことができ、中括弧は、ブロック文を作成するために使用されています

{ 
var foo = "bar"; 
var blah = "baz"; 
doSomething(); 
} 

上記の行は問題なくuated文字列とevalの内側に置くことができます。今、このことを考慮してください。

{ 
"foo": "bar", 
"blah": "baz" 
} 

中括弧は、それがグループ式、:文字の周りので、構文エラーだと思うためにJavaScriptエンジンを引き起こします。 MDN...JavaScript Guide...Object Literals

ステートメントの先頭にオブジェクトリテラルを使用しないでください。 { がブロックの先頭と解釈されるため、これによりエラーが発生するか、または期待どおりに動作しません。

()の中にオブジェクトリテラルをラップするのは、ブロックステートメントではなく、その内容を式として扱うようにエンジンに指示することで回避できます。

({ 
var foo = "bar"; 
var blah = "baz"; 
doSomething(evil); 
}) 
// parse error 

をしかし、これは行います:これは動作しません

({ 
"foo": "bar", 
"blah": "baz" 
}) 
// returns object 
関連する問題