2012-10-04 161 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)