2

したがって、fileList 配列の最初のファイルをロードするときに正しく呼び出される関数 fileLoaded では、this.loadAnother() を呼び出そうとしますが、Firefox は次のように主張します。

TypeError: this.loadAnother is not a function

関数ではないと主張するのはなぜですか?loadProjectSource() から正しく呼び出されていますが、次のファイルをロードしようとすると、関数ではありません。また、「これ」をデバッグすると奇妙な結果が得られるため、これが原因であると思われます。私は Javascript の専門家ではありませんが、この動作を見たことがありません。クラスの作成と関係がありますか? もしそうなら、loadProjectSource() からの最初の呼び出しが機能するのはなぜですか?

var ScriptLoader = Class.extend({ // Want to add functionality to this to allow PHP or inline loading...perhaps later
    init: function () {
        this.totalEngineToLoad = 0;
        this.totalEntitiesToLoad = 0;
        this.totalScenesToLoad = 0;
        this.totalLoaded = 0;
        this.entitiesToLoad = [0, 0, 0];
        this.fileList = ['./js/engine/Entity.js', './js/engine/Scene.js'];
        this.preload;
    },
    loadProjectSource: function (directory) {
        if(this.preload != null) {
            this.preload.close();
        }
        this.preload = new createjs.LoadQueue();
        this.preload.addEventListener("fileload", this.fileLoaded);
        this.preload.addEventListener("error", this.fileError);
        this.preload.setMaxConnections(5);
        this.loadAnother();
    },
    loadAnother: function () {
        var myItem = this.fileList.shift();
        if(this.fileList.length != 0) {
            this.preload.loadFile(myItem);
        }
    },
    fileLoaded: function (e) {
        debug('Loaded ' + e.item.src);
        debug(this.fileList);
    },
    fileError: function (e) {
        debug('Error ' + e.item.src);
    }
}
4

3 に答える 3

0

これは、コンテキスト バインディングが原因です。

この行で:

this.preload.addEventListener("fileload", this.fileLoaded);

thisコールバック関数のコンテキストはwindow、クラス インスタンスではなくオブジェクトになります。最新のブラウザーでは、次の方法で修正できます。

this.preload.addEventListener("fileload", this.fileLoaded.bind(this));

古いブラウザでは、次のようなものが必要です。

var self = this;
this.preload.addEventListener("fileload", function(){
    self.fileLoaded();
});

次の行も同じです。

于 2013-03-26T16:50:02.767 に答える
0

クラスは JavaScript では非常に奇妙です。少なくとも私の経験では、非常に面倒です。ScriptLoader クラスで、次のようなことを試してください (クラスの動作に合わせて変更する必要がある場合があります。とにかく、私はそれらを使用しません)。

SL = this;

次に、loadProjectSource 関数で、変更します

this.loadAnother();

SL.loadAnother();

ちょっとした考え!

于 2013-03-26T16:50:57.783 に答える
0

thisキーワードの値は、関数がどのように呼び出されるかによって異なります。また、イベント ハンドラーは、それを ScriptLoader インスタンスにしたいことを知りません。

適切なコンテキストを取得するには、次のいずれかが必要bindです

this.preload.addEventListener("fileload", this.fileLoaded.bind(this));

または、インスタンスで実際のメソッドを明示的に呼び出すハンドラーとして匿名関数を使用します。

var that = this;
this.preload.addEventListener("fileload", function(){
    // while "this" points to something indetermined, "that" is the instance
    that.fileLoaded();
});

TypeError は「this.loadAnother は関数ではありません」であり、それを呼び出そうとする唯一の場所は であるため、適切なコンテキストでそれを呼び出さないものloadProjectSourceに渡すことで同様の問題があるようです。loadProjectSource

于 2013-03-26T16:51:08.330 に答える