16

Firefox 3.5では、Firebugコンソールに次のように入力します。

false=={} // => evals to false
{}==false // syntax error

これの説明は何ですか?

4

3 に答える 3

41
{

ステートメントの開始時に、ステートメントのリストを含む「ステートメント ブロック」 ( ECMA-262-3セクション 12.1 を参照) を通知します。

}

ステートメントを含まないステートメント ブロックを直ちに終了します。それはいいです。しかし今、パーサーは次のステートメントを探しています。

==false

は?それは声明ではありません。構文エラー。

ステートメント ブロックとは何ですか? さて、あなたは次のように言うたびにステートメントブロックを書いています:

if (something) {
    ...
}

JavaScript は、これらのフロー制御ステートメントを次のように定義します。

if "(" <expression> ")" <statement> [else <statement>]

すなわち。中括弧なしの単一ステートメント形式で。次に、単一のステートメントを使用できる場所ならどこでもステートメント ブロックを使用できます。つまり、if-braces-many-statement を使用できます。しかし、フロー制御ステートメントが関連付けられていないステートメント ブロックを単独で使用できることも意味します。

これは実用的な目的にはまったく役立ちません。情報を隠していると思いたくなるかもしれませんが、そうではありません。

var a= 1;
{
    var a= 2;
}
alert(a);

...2ステートメントブロック自体は新しいスコープを作成しないため、結果は になります。

C (および C から派生した他の言語) が行ったように、JavaScript はこの方法でフロー制御とステートメント ブロックを定義します。ただし、これらの言語は{}、オブジェクト リテラル式として 2 つの役割を果たしませんでした。

このワナビーリテラルでさえ:

{
   a: 1
}

「:」はステートメント内のラベルを示すために使用されるため、有効なステートメント ブロックです。(and1は役に立たない式ステートメントで、セミコロンが省略されています。) ラベルは C から継承されたもう 1 つの機能で、JavaScript ではめったに使用されません。ブロックのように完全に無意味というわけではありませんが、ほとんど必要とされず、趣味が悪いと見なされることがよくあります。

(オブジェクト リテラルはコンマ区切りを使用するため、2 つのプロパティを持つリテラルは構文エラーを引き起こしますが、ラベル付きステートメントはセミコロンで区切る必要があります。)

これは、JavaScript の緩い構文が、式であると考えているものの別のステートメントを作成してつまずく可能性がある唯一の場所ではありません。

于 2009-10-02T13:56:41.137 に答える
11

OK、ECMAScript仕様(PDF)を調べましたが、 BNF文法について説明しています。

ECMAScriptソースは、次のように呼ばれるメインシンボルから解析されProgramます。

Program:
    SourceElements

SourceElementsの(再帰的)定義は次のとおりです。

SourceElements :
    SourceElement
    SourceElements SourceElement

SourceElementは、次のように定義されます。

SourceElement :
    Statement
    FunctionDeclaration

関心があるのはオブジェクトリテラル構文なので、FunctionDeclarationを無視し、Statementシンボルを確認します。

Statement :
    Block
    VariableStatement
    EmptyStatement
    ExpressionStatement
    IfStatement
    IterationStatement
    ContinueStatement
    BreakStatement
    ReturnStatement
    WithStatement
    LabelledStatement
    SwitchStatement
    ThrowStatement
    TryStatement

リストの順序が重要かどうかはわかりませんが(これが仕様に含まれている方法です)、...オブジェクトリテラルはExpressionStatementであり、標準では次のように記述されています(セクション12.4)。

ExpressionStatementは、ブロックであいまいになる可能性があるため、最初の中括弧で開始できないことに注意してください。また、ExpressionStatementはfunctionキーワードで開始できません。これは、FunctionDeclarationであいまいになる可能性があるためです。

したがって、プログラムの開始時に式がある場合がありますが、最初の中括弧({)で開始することはできません。そのため、次の作業は問題ありません。

  • ({} == false);
  • alert({} == false);
  • !{} == false;
于 2009-10-02T13:38:55.140 に答える
0

簡単に言うと、{}==falseは にコンパイルされて{};==falseいるため、構文エラーです。あなたが書くべき({})==falseであり、それはfalseを返します。

于 2012-01-05T07:51:26.800 に答える