JScriptにてsetTimeoutを不思議なかたちで呼び出す

昨日の続きです

@hasegawayosuke さんから示唆をうけました。
下記のコードでは不思議なことに、setTimeout関数を呼び出せます。但し、location.hash に何かセットしたときにそうなるように組んであります。

var dum,
sum = 0,
calc = function calc(x) {
var temp = x + 1;
return temp;
};

if (location.search > "?") {
dum = setTimeout('calc(sum)',2000);
} else {
dum = "";
}
clearTimeout(dum);
/* why? */
RuntimeObject("")["setTimeout"]("alert('wao!')",0500);

下記にテストを臨時に設けました。location.searchを与えたときのみif文にてsetTimeoutが使われて、if文終了後のRuntimeObject()が、setTimeoutを拾っているためか、'wao'とalertされまます。

どこがおもしろいのか

上の例では、setTimeoutが呼び出されているときに、RuntimeObject("")で作成されたオブジェクトには、setTimeoutがはいっているということになります。ところが、上のコードを若干改造して確かめてみてもらうとわかるのですが、このオブジェクトの中身をforループで拾い上げると、setTimeoutが、はいっていないようにみえるのです。setTimeoutは、for…inループによる列挙の対象外であり、RuntimeObject("")で作成されたオブジェクトにおいてDontEnum属性が付与されていると推理できます。

このことは、setTimeoutのかわりに、eval でも同じになっているようです。

さらに謎

(function(){
var s_tmp2 = setTimeout('',6000);
})();

var s_tmp2 = 0;
RuntimeObject("s*")["setTimeout"]("alert('wao!')",2000);

さらに謎です。よくわからないのですが、グローバルなスコープではないところで、setTimeoutを呼び出しているとします。このとき、グローバルな場所で、RuntimeObject("s*")で作成されたオブジェクトに、setTimeoutが格納されていることが、私には不思議でたまりません。

同様に、

(function(){
var add = new Function("x", "y", "return x + y");
})();

RuntimeObject("F*")["Function"]("return alert('uuummmm')")();

にてuuummmmがalertされます。

いたずらテスト

いたずら