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されます。