その手の平は尻もつかめるさ

ギジュツ的な事をメーンで書く予定です

dojo.require() をIE で使う時に注意すべき事

IE(IE 8) での話です*1
(ですから、FirefoxChrome 等のブラウザは無関係・無問題です)

dojo.require() で依存関係にあるJavaScript のソースを指定しているのにも関わらず
上手く動作しない(参照出来ない)、という問題にブチ当たったので書いておきます。

「オブジェクトを指定して下さい」

僕の書いたプログラムは、このTypeError のメッセージを吐いたきりプログラムが正常に動作しなくなりました。
しかし、なんという役に立たないエラーメッセージ……これがIE の開発者ツールクオリティ……^o^

で、このイカれたイカしたエラーメッセージが何を意味しているかを調べたところ、
「呼び出し先のfunction が見つからない(参照できない)」という事らしいです。*2

functionが見つからないとは

・サンプルソース1
dojo.provide('foo.script');

function fuga(message) {
    console.log(message);
}
・サンプルソース2
dojo.require('foo.script');

function hoge() {
    fuga('TEST');
}
この状態でサンプルソース2 のメソッドhoge() を呼ぶと、先の「オブジェクトを指定して下さい」というメッセージが出てきて、
プログラムが正常に動作しません。

調べてみたところ、
IEでのdojo.requireの挙動 | TechRacho
にあるように、IE ではdojo.require() でソースを指定しても、var やfunction がそのまま宣言されている場合は参照出来ないようです。
この記事で紹介されているように、dojo.declare() を利用しましょう。

dojo.declare() を使って解決する

dojo.declare() はクラスを作成するメソッドです。このメソッドを利用して問題を解決します。
具体的な解決方法としては、dojo.declare() を使ってサンプルソース1 にクラスを作成し、メソッドfuga() をそのクラスのインスタンスメソッドとしてから、
サンプルソース2 でサンプルソース1 のクラスのインスタンスを作り、そのインスタンスからメソッドfuga() を呼び出す、という段取りを踏みます。

ソースを見た方が手っ取り早い気がするので、ソースをいじります。
上記のサンプルソース1 を、dojo.declare() を使った形に修正します。
・サンプルソース1'
dojo.provide('foo.script');

dojo.declare('foo.script', null, {
    constructor: function() {
    },

    fuga: function(message) {
        console.log(message);
    }
});
という具合に手を加えます。(コンストラクタはおまじないに近いです。無くても大丈夫だと思います)
特にスーパクラス等は無いので、dojo.declare() の第2引数はnull にしました。

次に、サンプルソース2 を修正します。
・サンプルソース2'
dojo.require('foo.script');

var FooScript = new foo.script();
function hoge() {
    FooScript.fuga('TEST');
foo.script のインスタンスFooScript を作成し、そのインスタンスからメソッドfuga() を呼び出すことによって、
正常にメソッドfuga() を呼べるようになります。

そんな感じで

dojo.declare() を使ってクラス化してやると、IE でも依存関係にあるJavaScript のソースから
メソッドを呼び出すことが出来るようになりました。
メソッドに限らず、変数の場合でも同様の手順で参照可能に出来ると思います。

それでは。

*1:実に忌々しいことに

*2:だったら最初からそう書いて欲しい所ですが……