2012-03-29 3 views
9

が未定義であると考えられる:JavaScriptコンソールで(そしてなぜ){}が未定義ですか?明示的に評価されるまで、FFとChrome、{}の両方のコンソールで

{};  // undefined 
({}); // ▶ Object 

実際には、ビットは未定義未満で定義された - それは明らかに悪い構文は次のとおり

{} === undefined; // SyntaxError: Unexpected token === 
{}.constructor; // SyntaxError: Unexpected token . 

しかし、それは大丈夫です、その場合には、他の側にいない場合:

"[object Object]" == {}.toString(); // true 

するか、それが最初の式ではない場合:

undefined + undefined; // NaN 
{} + undefined;  // NaN 
undefined + {};  // "undefined[object Object]" 

何が得られますか?

+6

... f {UNDEFINED}とは何ですか?本当にそれは適切ではありません。あなたは言い換えることができますか? –

+0

コンソールは、必ずしも通常のJSに明示的にマッピングされているわけではありません。私は、これがchromeかFFコンソールかどうかは覚えていませんが、 '$(id)'と入力すると 'document 'と評価されることが分かります。getElementById(id) '(これは例えばjQueryで壊れます)。 – Alxandr

答えて

6

これは私の答えです。ここには新しいものはありません。私は文法のためのECMAScript仕様(のかなりのコピー)にリンクしているだけで、なぜそれがそうするかを解析する理由を示すためのいくつかのプロダクションを示しています。いずれの場合においても、行動には、JavaScript/ECMAScriptの文法規則に従って、明確に定義されている:{}は、それがである「コンテキスト」に応じて異なって解析され


のJavaScript REPL S(「コンソール」)スタート。文法生成または "文脈文脈"のStatementのコードを解析する。 (これは実際にはうそだ、それはProgramまたはSourceElementsのプロダクションから始まりますが、それを掘り下げるための追加の構造が追加されています)。ここでは、簡略化と省略を伴う概略文法の分解です。より多くのために上記のリンクを参照してください。

Statement 
    Block 
    ... 
    ExpressionStatement 

Block 
    # This is actually { StatementList[optional] }, but this is what 
    # it amounts to: * means "0 or more". 
    { Statement* } 

ExpressionStatement 
    # An ExpressionStatement can't start with "{" or "function" as 
    # "{" starts a Block and "function" starts a FunctionStatement. 
    [lookahead ∉ {{, function}]Expression ; 

Expression 
    # This is really PrimaryExpression; I skipped a few steps. 
    ... 
    (Expression) 

したがって(とき "文の文脈" で):

{} 
-> Block # with no StatementList (or "0 statements") 
-> Statement 

そして:

({}) 
-> (Expression) 
-> Expression 
-> ExpressionStatement # omitted in productions below 
-> Statement 

undefined === {}EXPR === EXPR -> EXPR -> STMT、結果として解析する理由も説明して評価されるとfalseになります。この場合の{}は、「表現コンテキスト」内にあります。

{} === undefinedの場合、構文エラーである{}; === undefinedまたはBLOCK; BOGUS -> STMT; BOGUSとして解析されます。ただし、かっこを追加すると、({} === undefined)(EXPR === EXPR) -> (EXPR) -> EXPR -> STMTとして解析されます。それは愚かであっても有効な構文であり、それは{}; + "hi"、又はBLOCK; + EXPR -> STMT; EXPR -> STMT; STMTとして解析され{} + "hi"の場合、

+この場合に単項です)。同様に、上記と同様に"hi" + {}{}を「式のコンテキスト」に置き、EXPR + EXPR -> EXPR -> STMTとして解析されます。

JavaScriptコンソールは、空の{}ブロックの「未定義」(実際には「何もありませんが、存在しません」)である最後のステートメントの結果を表示しています。 (これはブラウザ/環境によって異なりますが、最後のExpressionStatementなど、この場合に返される内容は異なる場合があります)

ハッピーコーディング。

1

表現が{で始まる場合、両方のコンソールがあいまいな条件として扱うようです。たぶんそれはダミーブロックとして扱われます。

これを試してみてください:

右手式として {}を使用して
{} // undefined 
undefined === {} // false 

は、曖昧さを取り除きます。外側の括弧は本当にダミーブロックとして扱われること

{a:42} // 42 
{{a:42}} // 42 
{{{a:42}}} // 42 

また、あなたから見ることができます。

これはコンソール機能ではないようです。 evalに渡されたときに、コンソールに入力するものは、実際に彼らはと同じように評価され得るという事実にほのめかしているようにもeval扱い、それらを、:

eval("{}") // undefined 
eval("{alert(42)}") // alerts 42 
+0

{} ===未定義はSyntaxErrorです、なぜですか?これは、同じ理由で –

+0

@JS_Riddler、: '{警告( "こんにちは")} ===は –

+0

undefined'申し訳ありませんが、私は自分自身で' '{}持つことを意味しました。答えを訂正しました。 –

0

問題はいくつかのケースでは、Javascriptを{見てということですと}を開閉するa/block /とする。それ以外の場合は、{}がオブジェクトです。ケースは本当にコンテキストに依存します。

10

中括弧を単独で使用すると、それはオブジェクトリテラルではなく、コードブロックです。コードブロックにはコードが含まれていないので、評価するとundefinedとなります。

+0

他の形式でも同じことが言えます。そのような場合、 '{}'は*式*として現れます。 –

+0

これは "{} === undefined"が構文エラーであり、 "undefined === {}"がどうしてそうでないかを説明していません。 –

+1

@JS_Riddlerはい、あります。 '{} === undefined'は' {} 'として解析されます。 === undefined'として、 '{}'が式として読み込まれない*場所に現れます。 '({} === undefined)'が動作します。これは、後者の場合、パーサはオブジェクトリテラル( "式として")として '{}'を読み込むためです。 –

0

Doug Crockfordがこれについて文句を言う。あなたがそこに着いているそのWTFは、+演算子自体のためです。算術と連結の両方に使用されます。最後の行では、+演算子が未定義を変換し、空のオブジェクトを文字列に変換して連結しています。

+0

これはこの場合問題ではありません。試してみてください。{}は式ではなく式ではなく "{}"の式であるため、 '{} +"は失敗します。 –

+0

いいえ、それらの連結の両方...最初は –

+0

「{}今式[対象オブジェクト]であるので、大丈夫」と第二の「{}は、ブロックではなく式であるため、[オブジェクトのオブジェクト]が失敗した」と評価されます@ pst:構文エラーではありません。最初のonは実際には '{};です。 + "somestring" .. '。文字列を数値に変換しようとすると 'NaN'が返されます –

2

コンソールに入力として{}と入力するだけであれば、中括弧が意味するものをその位置以外に解釈するコンテキストはありません。コンソールへの各入力が新しいコード行として解釈されるという事実を考えると、中括弧は新しいブロックの開始点と見なされます。空のブロックは、多くの場合、これらのような状況で使用されているので決算}は、構文的に正しいです:

それは左側にあり、そして空のブロックがあるとエラーを吐くことはありませんときしたがって {}は常に不定となります
try 
{ 
    //something 
} 
catch(e) 
{}//suppress error 

有効なコード。

+0

@pst、true ...私は私の答えを編集しました。 –

0

Javascriptは、ステートメントと式の概念を分離しています(C++やJavaなどの言語でも同じです)。

たとえば、if ...は文、x?y:zは式です。

式には値がありますが、文には値がありません。

{}は、式(この場合は空のオブジェクトコンストラクタを意味します)またはステートメント(この場合は空のコードブロックを意味します。基本的にはNOP)のいずれかになります。それがどのように解釈されるかは、文脈によって異なります。

関連する問題