Question

I have a simpe object in javascript which has few methods..Two of them I want to periodicaly call with window.setTimeout functions. My current code looks like this.

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

 };

}

The problem is apparently in my misunderstanding how scopes are working, it looks like when calling the function from timeout, it is called from another context where it actually doesn't exist?

Was it helpful?

Solution

Modified code: Scope of setTimeout is always window Object. you can Change context of function using call apply and bind(bind is not supported by older IE browsers 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);

    };
}

OTHER TIPS

call() takes as first parameter the context which the function is called from. This means that your this.call(context.stopShakeResolve, context) makes your context be context.stopShakeResolve which means that when the function is called this is equivalent to context.stopShakeResolve.

Just to make it clearer:

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

Does not have a function inside it called shakeResolver so it would throw an exception on you saying that it does not have property or method called this way. Change the call to the following:

this.stopShareResolve.call(this, context)
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top