문제

I was reading an article about requestAnimationFrame here, and I realized that I was having trouble following the scope and persistence of a variable. Slightly modified code below:

(function() {

    //Note: lastTime is defined up here.
    var lastTime = 0;

    var vendors = ['ms', 'moz', 'webkit', 'o'];

    //Okay, so they're trying to set window.rAF to the appropriate thing based on browser
    for(var x = 0; x < vendors.length && !window.requestAnimationFrame; ++x) {
        window.requestAnimationFrame = window[vendors[x]+'RequestAnimationFrame'];
        window.cancelRequestAnimationFrame = window[vendors[x]+
          'CancelRequestAnimationFrame'];
    }

    //...and if that doesn't work, turn it into a setTimeout
    if (!window.requestAnimationFrame)
        window.requestAnimationFrame = function(callback, element) {

            //I guess this is a way to make sure that the wait time
            //between renders is consistent

            var currTime = new Date().getTime();
            var timeToCall = Math.max(0, 16 - (currTime - lastTime));
            var id = window.setTimeout(function() { callback(currTime + timeToCall); }, 
              timeToCall);

            lastTime = currTime + timeToCall;

            //Wait. They just assigned lastTime a value.
            //Why is this going to persist between calls to window.rAF?
            //The variable lastTime was defined inside this function, not in the window.

            return id;
        };

    if (!window.cancelAnimationFrame)
        window.cancelAnimationFrame = function(id) {
            clearTimeout(id);
        };
}())

My guess is it has something to do with the function being placed inside parentheses, but how? What does this accomplish and what other effects can I expect with this coding style? Is this something I should start using more regularly, and if so, when?

도움이 되었습니까?

해결책

The variable lastTime here is captured via closure. This means it is kept alive beyond the scope of the function it is defined in.

A closure gets created anytime an anonymous function body references a variable outside of its own scope. Closures are extremely useful in JavaScript, as they allow you to maintain state without exposing it all globally.

To give a simplified example,

function foo() {
    var count = 0;

    setInterval(function bar() {
        console.log(count++);
    }, 100);
}

By closing over the count variable here, I can use it in setInterval without exposing count to the global scope as I would otherwise have to do.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top