evalの振舞い


細かいことばかりですみません。JavaScript の eval の振舞いについて調べていました。

eval について知りたいことがあったので ECMAScript の仕様書を眺めたのですが、どの環境で式を評価をするのかが明確に述べられていませんでした。そこで、Mac OS X 上で Safari (version 4 public beta, 5528.16), Firefox (3.0.6, Gecko 2009011912), v8 (version 0.3.0), Rhino (1.7 release 1 2008 03 06) を比較してみました。一応、どの処理系でも局所環境で評価しているようでした。

で、ぼくがやりたかったのは、局所環境のなかからevalを起動して大域環境で評価できないかということでした。で、結果はというと、システム依存ではあるものの Safari, Firefox, v8 ではできるようです。大域環境で、

var my_eval = eval;

と宣言し、局所環境から ”my_eval(expression);” のように起動すると、局所環境ではなく、大域環境で評価されます。Rhino で同じことをやると、「eval の間接呼び出しは禁止されています」というエラーメッセージを出しました。ECMAScript はといえば、間接呼び出しについてはエラーを投げてもよいという仕様なので、いずれのシステムの挙動も仕様の範疇にはいっているようです。

次に、別な局所環境で宣言された関数閉包の引数に eval を渡して、その関数閉包に式を評価させたらどのようになるか試してみました。以下のようなコードを走らせたときにどんなことになるか?

var a;

(function () {
var a;
var do_eval = function (eval, expr) {
eval(expr);
};
function () {
do_eval(eval, “a = 1;”);
}();
})();

Firefox と v8 は do_eval が宣言された環境、あるいは do_eval 本体の環境(確認していないけれど、たぶん、後者)で評価が行われているようでした。つまり、外側の function 式の内側で宣言された a に代入がなされました。

驚いたことに Rhino も同じ振舞いでした。

ところが、ところが、do_eval の引数で受けている変数の名前を eval から e に変更すると。。。Safari, Firefox, v8 は大域環境で評価をし、Rhino は例外を発生させます。

Safari は大域環境で評価するようです。

微妙な違いですけれど、微妙なことをしようとしているので、この違いは頭が痛いかも。。。

evalの振舞い」への1件のフィードバック

コメントは受け付けていません。