ActiveXObjectと同様なJScript固有オブジェクトにEnumeratorがある。これはCOMのコレクションインターフェイスをJScriptから操作するためにある(と思われる)
Enumeratorオブジェクトは、
// folderはfsoのFolderオブジェクトとする
// folder#Filesはfolderが示すディレクトリ内のファイルコレクション
var list = new Enumerator( folder.Files );
for(; ! list.atEnd(); list.moveNext()) {
// list#item()でコレクション要素(=fsoのFileオブジェクト)を取得
var file = list.item();
// あとはfileを操作する
}
のように、atEnd()メソッドがtrueを返すまでmoveNext()でループ処理を行い、コレクション要素を取得するのにitem()メソッドを使用する、という流れで使用するが、ちょっと独特のインターフェイスなためちょっと面倒に感じる。
以前のコマンドライン引数の展開ではラッパーオブジェクトを返す$E()関数を定義したが、今回は直接Enumerableにしてみる。
といっても別に面倒なことがあるわけではなく、_each()を実装後にEnumerableインターフェイスを追加するだけ。
// EnumeratorにEnumerableの機能を追加する
Enumerator.prototype._each = function(iterator) {
this.moveFirst();
for(; ! this.atEnd(); this.moveNext()) {
iterator( this.item() );
}
}
Object.extend( Enumerator.prototype, Enumerable );
こうして拡張されたEnumeratorを使用して、C:\直下のファイルを列挙するサンプルは以下のようになる。JScript.consoleは前回のエントリで試したオブジェクトとする。
new Enumerator( JScript.fso.GetFolder( "C:\\" ).Files ).each( function(file, index) {
JScript.console.println( index + " - " + file.Name );
} );
この方法なら、コレクションを配列にキャッシュしないので、たとえば1,000単位や10,000単位のファイルがあるディレクトリの操作でもたいしてメモリを消費せずにすむ(って前も書いたな)。
まとめとして、前回のエントリの定義+ライブラリロードを加えたサンプルを以下に示す。dummy.jsとprototype.jsは同じディレクトリにあるものとしている。
セコメントをする