2012-10-04 164 views
0

我在javascript中有一个simpe对象,它有很少的方法..其中两个我想定期调用window.setTimeout函数。我现在的代码看起来像这样。范围内的javascript

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); 

}; 

} 

的问题显然是在我的误解如何作用域工作,它看起来呼吁从超时功能时,它从另一个方面称为它实际上并不存在什么样的?

+0

在第一次调用'setTimeout'时,您立即执行一个函数并实际将*返回值*(它恰好是未定义的)作为超时后调用的函数。 (编辑:当然,假设你使用'this.call'调用通常的'Function.call'而不是你自己的变体。) – DCoder

+1

什么是'this'?它是一个函数吗?你怎么叫'shakeResolver'?要了解关于'this'的更多信息,请查看https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Operators/this。 –

回答

1

修改代码:setTimeout的作用域始终为window对象。您可以使用callapplybind更改功能的上下文(绑定不支持较早的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); 

    }; 
} 
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)