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调用this全局对象的函数(即,window在浏览器中)。(旁注:在严格模式下,它是undefined。)因此,当您不使用时bindthis brokenFunc现在是window而不是注册超时的对象。

为了保留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功能。出现第二个错误是因为this.constsis really window.consts,它不存在。that只需将调用包装在其范围内的匿名函数中,然后从that.

于 2013-01-23T21:32:16.247 回答