Javascript 匿名函数和变量作用域

Javascript 匿名函数和变量作用域,javascript,function,scope,anonymous,Javascript,Function,Scope,Anonymous,我正在读一篇关于requestAnimationFrame的文章,我意识到在跟踪变量的作用域和持久性时遇到了问题。略加修改的代码如下: (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

我正在读一篇关于requestAnimationFrame的文章,我意识到在跟踪变量的作用域和持久性时遇到了问题。略加修改的代码如下:

(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);
        };
}())
(函数(){
//注意:这里定义了lastTime。
var lastTime=0;
var供应商=['ms','moz','webkit','o'];
//好的,所以他们正试图根据浏览器将window.rAF设置为适当的值
对于(var x=0;x

我猜这和函数放在括号里有关,但是怎么做呢?这能实现什么?这种编码风格还能带来什么其他效果?这是我应该开始更经常使用的东西吗?如果是,什么时候?

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

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

举个简单的例子

function foo() {
    var count = 0;

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

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

此处的变量
lastTime
是通过以下方式捕获的。这意味着它在其定义的函数范围之外保持活动状态

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

举个简单的例子

function foo() {
    var count = 0;

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

通过关闭这里的
count
变量,我可以在
setInterval
中使用它,而不必像其他方法那样将
count
暴露到全局范围。

这是否意味着window.requestAnimationFrame现在具有包括匿名函数的范围?我的想法如下:(1)全局通常是指
窗口
对象内部(2)此匿名函数存在于其自身空间中,因为其变量无法全局访问(3)通过将函数分配给window.requestAnimationFrame,函数现在存在于
窗口
对象中,远离匿名函数,因此它无法访问匿名函数的变量,所有这些点通常都是正确的。对于3,它只能访问已关闭的变量。定义回调函数时关闭变量;因此,您的回调函数稍后无法(通过
eval
)尝试获取匿名函数的另一个变量,因为已经太晚了。这是否意味着window.requestAnimationFrame现在具有包含匿名函数的作用域?我的想法如下:(1)全局通常是指
窗口
对象内部(2)此匿名函数存在于其自身空间中,因为其变量无法全局访问(3)通过将函数分配给window.requestAnimationFrame,函数现在存在于
窗口
对象中,远离匿名函数,因此它无法访问匿名函数的变量,所有这些点通常都是正确的。对于3,它只能访问已关闭的变量。定义回调函数时关闭变量;因此,您的回调函数不能稍后(通过
eval
)尝试获取匿名函数的另一个变量,因为已经太晚了。