Hatena::Groupmoz-addon

Ci.nsIZIGOROu

2007-10-20記事書けない

ScriptControl (1)

| 05:59 |  ScriptControl (1) - Ci.nsIZIGOROu を含むブックマーク はてなブックマーク -  ScriptControl (1) - Ci.nsIZIGOROu

ScriptControlを使うと現在のActiveScriptのコンテキスト中に異なるActiveScriptのコンテキストを混在させる事が出来ます。

分かりやすい例で言えば、ブラウザの中でのwindowオブジェクトはGlobalオブジェクトですが、iframe内のcontentWindowもやはりGlobalオブジェクト。しかしこれらは異なります。

従ってwindow.Objectとiframe.contentWindow.Objectは異なるコンストラクタです。

ScriptControlについても同じ事が言えます。

var sctl = WScript.CreateObject("ScriptControl");
sctl.Language = "JScript";

WScript.Echo(sctl.Modules.Item(1).CodeObject.Object); // [native code]が出る
WScript.Echo(String(Object == sctl.Modules.Item(1).CodeObject.Object)); // false

って感じですね。つまり異なるGlobalオブジェクトになる訳です。

今度は他のGlobalオブジェクト内にコンストラクタを定義した場合、

sctl.Modules.Item(1).AddCode('function TestObject() { this.foo = 1; }');
var testobj;
try {
  testobj = new sctl.Modules.Item(1).CodeObject.TestObject();
}
catch (e) {
  WScript.Echo(e.message);
}

これは「引数の数が一致していません。または不正なプロパティを指定しています。」などと言われて怒られます。

所が、

testobj = sctl.Modules.Item(1).Eval('new TestObject();');

は見事にTestObjectを生成する事が出来ます。

あるいは、

var TestObject = sctl.Modules.Item(1).CodeObject.TestObject;
testobj = new TestObject();

とすれば、普通に実行出来るようです。

sctl.Modules.Item(1).AddCode('TestObject.prototype.getFoo = function() { return this.foo; };');                                        
var TestObject = sctl.Modules.Item(1).CodeObject.TestObject;                                                                           
WScript.Echo((new TestObject).getFoo()); // 1

これは問題無く出来た。まぁ当たり前かw

sctl.Modules.Add("Foo");

で新しいModuleを定義出来るんですけど、この時のAddメソッドの第二引数のオブジェクトが代入出来る事になってるんだけど、これの意味が分からない。

追記1 (2007-10-23T02:36:47+09:00)

id:nanto_viさんに頂いたコメントを折角だから本文に再掲。*1

これは
new sctl.Modules.Item(1).CodeObject.TestObject()
(new sctl.Modules.Item(1)).CodeObject.TestObject()
と解釈されて、sctrl.Modules.Item がコンストラクタではないためですね。
new (sctl.Modules.Item(1).CodeObject.TestObject)()
とすれば無事オブジェクトを生成できます。 id:nanto_viさんのコメント

今確かめたけど、確かに出来ました。すごー。

ところで何故Itemで切れちゃうのかは分からない。w

*1:いつも助け舟頂いて恐縮です。><

nanto_vinanto_vi2007/10/23 01:14> これは「引数の数が一致していません。または不正なプロパティを指定しています。」などと言われて怒られます。

これは
new sctl.Modules.Item(1).CodeObject.TestObject()

(new sctl.Modules.Item(1)).CodeObject.TestObject()
と解釈されて、sctrl.Modules.Item がコンストラクタではないためですね。
new (sctl.Modules.Item(1).CodeObject.TestObject)()
とすれば無事オブジェクトを生成できます。

ZIGOROuZIGOROu2007/10/23 02:35> id:nanto_viさん

いつもありがとうございます。なるほど、とても納得しました。
実はこれはとあるネタの複線だったりするんで、そう書けるとなると相当楽になりそうです。

nanto_vinanto_vi2007/10/26 23:37> 何故Itemで切れちゃうのかは分からない。

なぜかといわれれば、new演算子の優先順位が関数呼び出しより高いからというのが答えになるでしょうか。でないと new Date().getTime() なども期待したとおり動きませんし。

ZIGOROuZIGOROu2007/10/27 02:42なるほどー。勉強になります。