匿名函数和变量范围

时间:2013-09-20 18:31:17

标签: javascript function scope anonymous

我正在阅读一篇关于requestAnimationFrame here的文章,我意识到我在跟踪变量的范围和持久性时遇到了麻烦。下面稍作修改的代码:

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

我的猜测是它与放在括号内的功能有关,但是如何?这可以实现什么,以及这种编码风格我可以期待的其他效果?这是我应该开始更频繁地使用的东西,如果是的话,何时?

1 个答案:

答案 0 :(得分:3)

此处的变量lastTime通过closure捕获。这意味着它保持活动超出了它定义的函数的范围。

只要匿名函数体引用其自身范围之外的变量,就会创建闭包。闭包在JavaScript中非常有用,因为它们允许您在不全局公开状态的情况下维护状态。

举一个简化的例子,

function foo() {
    var count = 0;

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

通过在此处关闭count变量,我可以在setInterval中使用它,而不会将count暴露给全局范围,否则我将不得不这样做。