2011-12-24 13 views
4

この質問は、the accepted answer hereからインスパイアされています。次のコードが「最初」、その後に「秒」、その後エラーが「TypeError」と表示されるのはなぜですか?2つの連続した自己実行匿名関数を持つタイプエラー

ここでの説明は、最初の関数の戻り値が呼び出されることです。しかし、なぜそれが起こったのですか? [また、なぜセミコロン挿入が最初に自己の実行後にセミコロンを追加しましたか?]

答えて

5

セミコロンがなければ、それはと評価されます:最初の関数が実行される

(function() { 
    alert('first'); 
}())(function() { 
    alert('second'); 
}()) 

、それ以来、そう、そして、第二の機能が実行され、それが再びundefined返し

undefined(function() { 
    alert('second'); 
}()) 

:それはそれがさらに評価され、何も返さない

undefined(undefined) 

もちろん動作しません(undefinedは機能ではないため、TypeError)。個々の関数呼び出しはセミコロンで区切る必要があります。

+0

今すぐご覧ください!しかし、なぜセミコロンの挿入がここに入っていないのですか? – Randomblue

+0

@Randomblue:仕様のルールには適用されません:http://es5.github.com/#x7.9.1。呼び出しは、 '[noLineTerminator here]'を必要としない 'CallExpression: MemberExpression Arguments'と定義されているので、セミコロンは挿入しないでください。 (これは、例えば、 'return'とは逆ですが、その要求を持ち、セミコロンが挿入されています。) – pimvdb

+0

@Randomblueこれは理由がないからです。セミコロンは、それらがなければ意味をなさない文の後にのみ挿入されます。ここのルールを参照してください:http://es5.github.com/#x7.9 – Zirak

2

ASI、自動セミコロン挿入。あなたのコードは次のように書かれてきたはずです。

代わり
(function() { 
    alert('first'); 
}()); //<--semicolon 


(function() { 
    alert('second'); 
}()); //<--semicolon 

は、ここに取られるステップです。そのため、

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


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

//now, the interpreter guesses that you mean to concatenate the two 
(function() { 
    alert('first'); 
}())(function() { 
    alert('second'); 
}()); 
//it also inserts a semi-colon where it should've appeared at the end of the script 

//first function doesn't return anything === returns undefined 
undefined(function() { 
    alert('second'); 
}()); 

//second function doesn't return anything === returns undefined 
undefined(undefined); 
//however, the braces stay, since they can also mean function execution 

undefinedは、したがって、それが実行できない機能はありませんが、あなたが得ますTypeError。

+0

ありがとうございます。しかし、なぜインタプリタはASIを連結すると思いますか? – Randomblue

+0

@Randomblue ASIは、セミコロンが存在しない場合に解析エラーがスローされる場合にのみ起動します。言い換えれば、セミコロンが必要な場合、改行文字のようなものがあります。ルールはhttp://es5.github.com/#x7で非常によく定義されています。9 – Zirak

+1

ルール#3はクリスタルとしてはっきりしています! –

1

これはプログラムが解析されたためです。私たちは、

(some stuff) (some more stuff) 

などのプログラムをsumarise可能性があり、これは関数としてsome stuffを呼び出そうとする必要があることは明らかです。もちろん、セミコロンで問題が解決され、セミコロンの挿入が自動的に行われることを期待していました。詳細な挿入ルールがわからなければ、ルールは明確に定義されていないため、明確に定義されていない動作を変更しないように、何も挿入されていないと言います。

もちろん、この動作は「明確に定義されている」とは考えられないかもしれません。しかし、言語のルールはあらゆる状況でうまく機能しません。

関連する問題