【问题标题】:Anonymous Functions and Variable Scope匿名函数和变量范围
【发布时间】:2013-09-20 18:31:17
【问题描述】:

我正在阅读一篇关于 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);
        };
}())

我的猜测是它与放在括号内的函数有关,但是如何?使用这种编码风格可以完成什么以及我可以期待什么其他效果?这是我应该开始更经常使用的东西吗?如果是,什么时候开始?

【问题讨论】:

    标签: javascript function scope anonymous


    【解决方案1】:

    这里的变量lastTime是通过closure捕获的。这意味着它在其定义的函数范围之外保持活动状态。

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

    举个简单的例子,

    function foo() {
        var count = 0;
    
        setInterval(function bar() {
            console.log(count++);
        }, 100);
    }
    

    通过在此处关闭 count 变量,我可以在 setInterval 中使用它,而无需像其他情况下那样将 count 暴露在全局范围内。

    【讨论】:

    • 这是否意味着 window.requestAnimationFrame 现在具有包括匿名函数的范围?我想到的事情如下:(1)全局通常意味着window对象内部(2)这个匿名函数存在于它自己的空间中,因为它的变量不能全局访问(3)通过将函数分配给window。 requestAnimationFrame,该函数现在存在于window对象中,远离匿名函数,因此无法访问匿名函数的变量
    • 是的,所有这些点通常都是正确的。对于 3,它只能访问它已经关闭的变量。定义回调函数时关闭变量;所以你的回调函数不能,比如说,稍后(通过eval)尝试获取另一个匿名函数的变量,因为已经太晚了。
    猜你喜欢
    • 2011-10-27
    • 1970-01-01
    • 1970-01-01
    • 2010-12-19
    • 1970-01-01
    • 1970-01-01
    • 2015-08-25
    • 1970-01-01
    • 2015-09-20
    相关资源
    最近更新 更多