Search code examples
javascriptsettimeoutprivate-methods

setTimeout for a function of a private object


I'm trying to set timeout to a function of an object, which is a private function of another object. Actually the structure is something like this:

function MainObject() {
    var id;
    ...
    var InnerObject = function() {
        this.getSomething = function() { ... }
    }

    this.testFunc = function() {
        id = setTimeout(InnerObject.getSomething(), 1000);
    }
}

...and it won't work as it says 'undefined' when trying to set timeout, and I can't execute this function directly as it's a private function. What am I doing wrong? Tried to find something particular but didn't success. I see the error might be somewhere in scope problems, but still don't get it


Solution

  • Since you've given us little to go on for why you've chosen a complicated approach, I will simplify things into something that will work.

    function MainObject() {
        var id;
        ...
        function getSomething() {
            // code here
        }
    
        this.testFunc = function() {
            id = setTimeout(getSomething, 1000);
        }
    }
    

    Things wrong with your approach:

    1. InnerObject looks a constructor function, but you never actually call it.
    2. Because InnerObject is a constructor function, there is no InnerObject.getSomething property. If you did var obj = new InnerObject(), then there would be an obj.getSomething property you could call.
    3. You pass a function reference to setTimeout(). Unless getSomething() returns a function, you don't want to call it, you would want to pass just the function reference without the parens.

    If you really wanted to keep the InnerObject, then you'd have to actually instantiate an object with that constructor like this:

    function MainObject() {
        var id;
        ...
        var InnerObject = function() {
            this.getSomething = function() { ... }
        }
        // call your constructor and create an object
        var obj = new InnerObject();
    
        this.testFunc = function() {
            id = setTimeout(obj.getSomething.bind(obj), 1000);
        }
    }
    

    Note: the .bind(obj) is used so that the this pointer is set correctly when getSomething() is called by the timer code.