1

このような構造のクラスがあります

function myClass () {
    this.varA = 0;
}

myClass.prototype.consts = {
    someConst : 1,
    anotherConst : 1000,
}

myClass.prototype.startIt = function () {
    window.setTimeout(this.brokenFunc.bind(this), this.consts.anotherConst);
}

myClass.prototype.brokenFunc = function () {
    this.varA += this.consts.someConst;

    window.setTimeout(this.brokenFunc.bind(this), this.consts.anotherConst); 
}

// Example call
var myObj = new myClass();
myObj.startIt();

これはほとんどの Android デバイスで問題なく動作しますが、Android 2.3 を実行しているユーザーから、動作しないとの連絡があり、エミュレータでエラーを再現できました。まず、TypeError: Result of expression 'this.brokenFunc.bind' [undefined] is not a functionこの行 ( 内startIt)について次のように述べています。

window.setTimeout(this.brokenFunc.bind(this), this.consts.anotherConst); 

結構だ、と私は考え、電話var _this = thisを回避するために昔ながらのトリックを実行しました。bindしかし、今ではTypeError: Result of expression 'this.consts' [undefined] is not an objectこの行で言う

this.varA += this.consts.someConst;

そして、私は少し迷っています。このコードが機能しないのはなぜですか? 特に、ほとんどの Android バージョンで動作するためです。

4

1 に答える 1

1

デフォルトでは、 はグローバル オブジェクト (つまり、ブラウザ内) を使用してsetTimeout関数を呼び出します。(補足: 厳密モードでは、代わりに です。) したがって、 を使用しない場合、タイムアウトを登録したオブジェクトの代わりにが使用されるようになりました。thiswindowundefinedbindthis brokenFuncwindow

thisfromを保持するにstartItは、呼び出しを無名関数でラップする必要があります。

myClass.prototype.startIt = function () {
    var that = this;

    window.setTimeout(function() {
        // call brokenFunc with the outer this
        that.brokenFunc();
    }, this.consts.anotherConst);
}

最初のエラーは、Android 2.3 ブラウザーが EMCAScript 5bind関数をサポートしていないために発生しました。2 番目のエラーが表示されたのは、this.consts実際window.constsには存在しないためです。thatスコープ内にある無名関数で呼び出しをラップし、から関数を呼び出すだけthatです。

于 2013-01-23T21:32:16.247 に答える