0

I've spent a lot of time dealing with understanding this, func.bind(this), func.bind(exports), and function() { that.func(); }. What I can't wrap my mind around though, is how is the following setTimeout capable of seeing and accessing doStuff() in the private scope, when no export for it has been defined in the module?

window.TestModule = (function() {
    function init() {
        document.getElementById('testbt').onclick = test;
    }

    function test() {
        setTimeout(function() {
            alert(this);        //window
            doStuff();          //works! wow!
        }, 250);
    }

    function doStuff() {
        //do stuff
    }

    return {
        init: init
    };
}());

TestModule.init();
wayofthefuture
  • 8,339
  • 7
  • 36
  • 53

1 Answers1

1

doStuff is in the scope, that's why. It can't find it in setTimeout(function(){}), so it looks to the next scope. It can't find it in function test () {}, so it looks to the next scope. It finds it in (function(){})() and uses that definition.

If you didn't define doStuff, it would throw a ReferenceError because it will eventually reach the window scope without finding it, and there won't be a next scope to look to.


Also, I don't think that's your real code; it has a syntax error. Mind posting an actual, working scenario?
RK.
  • 867
  • 2
  • 10
  • 19
  • I'd post the real world example, but its HUGE. Do you think anything is wrong with that above design pattern? It is really great, no more this / exports in the onclick event! – wayofthefuture Sep 06 '15 at 21:40
  • No, nothing seems wrong... except for the syntax error lurking in the corner. – RK. Sep 06 '15 at 21:43
  • What if there was a function window.doStuff as well, would it call the window.doStuff instead of the private one? – wayofthefuture Sep 06 '15 at 22:00
  • No, it would call the private one, because the private `doStuff`'s scope is closer to the current scope than `window.doStuff`. – RK. Sep 06 '15 at 22:03
  • what is this concept called? – Ringo Sep 06 '15 at 22:12
  • What concept exactly? Scoping? – RK. Sep 06 '15 at 22:13
  • I don't think javascript looks for the existence of a function in the closest scope and executes it. Is that what you're saying? – Ringo Sep 06 '15 at 22:17
  • Yes, that's what I'm saying. I've read somewhere that it does this, I could look it up if you want. – RK. Sep 06 '15 at 22:19
  • I think you're right, actually. I made jsfiddle here: http://jsfiddle.net/vr57pqwu/5/ If you uncomment each doStuff(), it keeps looking up a level for the function, even in the window context. – Ringo Sep 06 '15 at 22:25
  • So setTimeout keeps a map of the scopes internally, kind of like a scope chain? – wayofthefuture Sep 06 '15 at 23:12
  • It has nothing to do with `setTimeout`. – RK. Sep 06 '15 at 23:18
  • Do you know of any links that would explain internally how scope walking works in this scenario? Thanks – wayofthefuture Sep 06 '15 at 23:27