1、2 番目の理由は簡単。
{ "name": "noname", "age": 19, "datas": [0, 1, 2, 3, 4] }
// ステートメント冒頭の「{」がブロック開始と見なされ、続く「:」はラベルと見なされる
// → SyntaxError: invalid label
3、4 番目は少しややこしい。まず、以下のルールを ECMA 262-3 から引っ張ってくる。
・ステートメントにも(仮想的な)戻り値がある(§8.9)。
・関数宣言は戻り値として empty を返す(§14)。
・eval() は、評価結果が中途終了ではなく、かつ値が empty なら undefined を、それ以外ならその値を返す(§15.1.2.1)。
これをベースに、eval() の戻り値を確認する。
eval ('function test() { alert(1); }');
// IE:undefined, Fx:undefined, Op:undefined, Sa:undefined
これは明らかに関数宣言であり、全ブラウザの挙動は上記ルールに合致する。
eval('function() { alert(1); }');
// IE:undefined, Fx:Function, Op:SyntaxError, Sa:Function
関数に名前がないことから関数宣言ではないことは明らか。しかし、ステートメント冒頭の式は function で始まってはならないというルールもある(§12.4)ので関数式でもない。曖昧。
eval('(function() { alert(1); })');
// IE:undefined, Fx:Function, Op:Function, Sa:Function
これは明らかに関数式なので、Function オブジェクトを返さねばならない。
と言うわけで、IE(JScript)の挙動はよく分からない。IE は関数とスコープの扱いが微妙なので、Function() を併用することになると思うが、スコープがグローバルになるのがこれまた微妙。