UWSCでjavascriptのarrayを使う
前に連想配列を検討したときも悩んだんですよね。
UWSCで連想配列を配列にする - じゅんじゅんのきまぐれ
stuncloudさんも微妙に思ったようなので、考えてみた。
UWSCでjson | たっぷす庵
現状の問題
stuncloudさんのスクリプトを流用して問題を提示。
DIM sc = CreateOleObj("ScriptControl") sc.Language = "JScript" DIM i, j = sc.Eval("(" + json + ");") print j.test.a print LENGTH(j.test.b) // 2じゃない! print j.test.b[0] // エラー!!! textblock json { "test":{ "a":"abcde", "b":["111111", "222222"] } } endtextblock
もとのように、Arrayオブジェクトへのアクセスをgetoleitemでやっても良いけど、、、all_ole_itemに入るのが微妙だったりするんですよね。
二重ループできなくなるし。
ということで、解決していきましょう。
LENGTH問題
javascriptのArrayをUWSCのLENGTH関数に渡しても、長さが取れない。
これは簡単。
print j.test.b.length
にするだけ。
これで、期待通り2になります。
要素へのアクセス問題
どうも、[]によるアクセスができないみたいなんですよね。
ということで、対策を考えてみた。
以下は注釈がなければ、
print j.test.b[0] // エラー!!!
を書き換える想定でお読み下さい。
また、取得側しか書きませんが、設定側も同様です。
関数追加案
sc.AddCode("function Get(o,i) { return o[i]; }") print sc.Run("Get", j.test.b, 0)
AddCodeを一度やれば、Runで取得できる。
ただ、スマートじゃないですよね。
オブジェクトに対する影響が少ないのがメリット。
対象オブジェクトに関数追加案
これは、textblockも変更する。
print j.test.Get(j.test.b, 0) textblock json { "test":{ "a":"abcde", "b":["111111", "222222"], "Get":function(o,i) { return o[i]; } } } endtextblock
j.testがくどい、、、。
関数名が文字列でないのが精神衛生上マシな感じ。
対象オブジェクトに専用関数追加案
これも、textblockを変更する。
print j.test.GetB(0) textblock json { "test":{ "a":"abcde", "b":["111111", "222222"], "GetB":function(i) { return this.b[i]; } } } endtextblock
見栄えはマシになりましたが、Arrayオブジェクトがあるだけ関数を増やす必要があります、、、。
Array変更案
これは、textblockはもとのまま。
sc.ExecuteStatement("Array.prototype.Get = function(i) { return this[i]; }") print j.test.b.Get(0)
[]でアクセスしたいのはやまやまですが、これが妥協案でしょうか。
ブラウザで実行するようなスクリプトでArrayを直接変更するようなことは、あまりしたくないですが、ま、ScriptControl内のことなので、良いでしょう。
これも、ExecuteStatementは一度やれば全てのArrayが変更されます。
javascriptのオブジェクトはそういうものなのです。