JScript ファイルに一行加え、インクルードを実現する方法

2012-04-14 08:57:35 | Programming > JScript
はじめに
JScript にはスクリプト単体でインクルードが可能な関数やステートメントは提供されていない。そこでスクリプト コンポーネントを用いて、これを実現する方法を考えてみた。たった一行加えるだけのシンプルなコードである。JScript の eval が抱える実行コンテキストの問題も解決している。興味のある方は是非一度試していただきたい。

※現在は Include コンポーネントの機能の一つとして公開しています。

Include コンポーネント
基本的な機能の紹介やダウンロード先は Include コンポーネントのページを参照のこと。

構文
Include コンポーネントをアクティブ化することで $include というインクルード用の関数が使えるようになる。
($=new ActiveXObject('JScript.Include'))(this);
$include('C:\...\js\module1.js');
$include('C:\...\js\module2.js');
$include('C:\...\js\module3.js');


文字コードの指定
インクルードされる JScript ファイル(以下 "モジュール" )は UTF-8 として読み込まれる。それ以外の文字コードで書かれている場合は第二引数で指定する。"_autodetect" は自動検出の指定だが、誤判定の可能性もあるのであまりお勧めしない。
$include('C:\\...\\js\\module1.js', 'shift_jis');
$include('C:\\...\\js\\module2.js', 'euc-jp');
$include('C:\\...\\js\\module3.js', '_autodetect');
モジュールのデフォルト文字コードを変更したい場合は前述の構文において、第二引数以降にそのパスを指定する。
($=new ActiveXObject('JScript.Include'))(this, 'shift_jis');
$include('C:\\...\\js\\module1.js');
$include('C:\\...\\js\\module2.js');
$include('C:\\...\\js\\module3.js');
さらに個別指定しても構わない。
($=new ActiveXObject('JScript.Include'))(this, 'shift_jis');
$include('C:\\...\\js\\module1.js');
$include('C:\\...\\js\\module2.js', 'euc-jp');
$include('C:\\...\\js\\module3.js', 'utf-8');


パスの指定
モジュールのパスは絶対パスによる指定が基本だが、相対パスで指定した場合は呼び出し元 JScript ファイルが置かれたディレクトリを基準としてパスを補完する(スクリプト ホストが Windows Script Host の場合のみ)。すべてのモジュールが同一ディレクトリにあるなら
($=new ActiveXObject('JScript.Include'))(this);
$include('module1.js');
$include('module2.js');
$include('module3.js');
もちろん「.」や「..」、環境変数も使える。
($=new ActiveXObject('JScript.Include'))(this);
$include('.\\module1.js');
$include('..\\module2.js');
$include('%USERPROFILE%\\My Documents\\js\\module3.js');
セパレータに "/" を使ってもよい。このあたりはお好みで。
($=new ActiveXObject('JScript.Include'))(this);
$include('./module1.js');
$include('../module2.js');
$include('%USERPROFILE%/My Documents/js/module3.js');
モジュールが特定のディレクトリにまとめて置かれている場合は、そのディレクトリを相対パスの基準とすることもできる。これは前述の構文において、第二引数以降にそのパスを指定する(環境変数も可)。
($=new ActiveXObject('JScript.Include'))(this, 'D:\\...\\js');
$include('module1.js');
$include('module2.js');
$include('module3.js');
同時にデフォルト文字コードの指定も可能。第二引数以降は順不同および省略可能である。
($=new ActiveXObject('JScript.Include'))(this, 'shift_jis', 'D:\\...\\js');
($=new ActiveXObject('JScript.Include'))(this, 'D:\\...\\js', 'shift_jis');


戻り値とエラー
$include 関数はモジュールが存在しない場合であってもエラーを発生させない。ただし戻り値に false が返る(成功時は true)。


$include の実装について
大まかな流れとしてはコンポーネント側でスクリプト側のグローバル オブジェクトの eval を呼び出すメソッドを用意し、それをスクリプト側の $include 変数に代入しているだけである。本来 eval は呼び出し元コンテキストのスコープチェーンを辿るが、スクリプト側とコンポーネント側ではスコープ チェーンが独立しているため、eval に適用されるコンテキストはコンポーネント側の関数コンテキストではなく、スクリプト側で $include を呼び出したコンテキストとなる。つまり $include 関数は動的スコープになっているのである。本来できないと思われていた eval の処理を関数化できたのはそのためである。


JSCript > Include コンポーネント

最新の画像もっと見る

2 コメント

コメント日が  古い順  |   新しい順
Unknown (frogie)
2013-01-16 18:57:28
大変参考になりました。
ありがとうございました!
返信する
>frogie さん! (gw)
2013-01-17 23:34:14
こんなマニアックな記事にお付き合い下さり
ありがとうございます(笑)。
返信する