0

我在 javascript 中有一个 simpe 对象,它的方法很少。其中两个我想用window.setTimeout函数定期调用。我当前的代码如下所示。

var shakeResolver = function () {
 var resolveTimeout;
 console.log(this);
 var context = this;
 this.startShakeResolve = function () {
     this.resolveTimeout = window.setTimeout(this.call(context.stopShakeResolve, context), 2000);
     $(window)
         .on('devicemotion', this.onDeviceMotion);
 };

 this.onDeviceMotion = function (event) {};

 this.stopShakeResolve = function (context) {
     this.resolveTimeout = window.setTimeout(context.startShakeResolve, settings.interval);

 };

}

问题显然是我误解了范围是如何工作的,看起来从超时调用函数时,它是从另一个实际上不存在的上下文中调用的?

4

2 回答 2

1

call()将调用函数的上下文作为第一个参数。这意味着您this.call(context.stopShakeResolve, context)使您的上下文成为context.stopShakeResolve,这意味着调用函数时this等效于context.stopShakeResolve.

只是为了更清楚:

this.stopShakeResolve = function (context) {
    this.resolveTimeout = window.setTimeout(context.startShakeResolve, settings.interval);
};

它内部没有调用的函数,shakeResolver因此它会向您抛出异常,说它没有以这种方式调用的属性或方法。将调用更改为以下内容:

this.stopShareResolve.call(this, context)
于 2012-10-04T08:09:25.560 回答
1

修改后的代码:setTimeout 的范围始终是windowObject。call apply您可以使用and更改函数的上下文bind(旧的 IE 浏览器 IE <= 8 不支持绑定)。

var shakeResolver = function() {
    this.resolveTimeout;
    console.log(this);
    var context = this;
    this.startShakeResolve = function() {
        this.resolveTimeout = window.setTimeout(function() {
            context.stopShakeResolve.apply(context, arguments);
        }, 2000);

        $(window).on('devicemotion', function(){
                    context.onDeviceMotion.apply(context, arguments);
            });
    };

    this.onDeviceMotion = function(event) {
    };

    this.stopShakeResolve = function(context) {
        this.resolveTimeout = window.setTimeout(function() {
            context.startShakeResolve.apply(context, arguments)
        }, settings.interval);

    };
}
于 2012-10-04T08:11:42.317 回答