setTimeout 学习闭包

@(技术笔记)[css]

学习参考网站

css 网站,可供参考

javascript学习网站

var create = function (i){
    return function(){
        console.log(i);
    };
};

for ( var i = 0; i < 5; i++ ) {
    console.log(i);
    setTimeout( create(i), i * 1000 );
}

上面代码运行解释:

这是一个倒计时代码片段!
javascript的到计时代码并不是那么好写的哈。呵呵

setTimeout 是一个异步执行的函数。函数定义如下:
Alt text
第一个参数是要执行的方法(function),第二个参数是延迟时间。

好的。那我们这样写会有什么结果:

for ( var i = 0; i < 4; i++ ) {
    setTimeout( function () {console.log(i)}, i * 1000 );
}

输出结果为

4
4
4
4

我是这样理解的,setTimeout函数式异步函数,它会在for循环结束后执行。这时候在运行栈中的匿名函数i的值为4,所以运行的结果都为4。

步骤如下:

  1. 第一个for循环,在栈中压入带执行的方法
    setTimeout( function () {console.log(i)}, i * 1000 );
    此时i为1.
  2. 第二次for循环,在栈中压入待执行的方法
    setTimeout( function () {console.log(i)}, i * 1000 );
    此时i为2。这个i是个全局变量,所以此时第一压入栈中的函数i也为2.

以下重复上面步骤,最后压入栈中待执行的函数指向的变量值都为4.

所以最终的输出结果为 上面所示。

那么我们如何才能输出4个不一样的值呢?
如何让函数保存住它的变量。

for (var i = 0; i < 4; i++) {
    setTimeout(create(i), i * 1000);
}

create(i) 是执行函数create并传入参数i,这个函数会立刻执行,这个函数执行完后有一个返回值。这个返回值也是一个函数,这个函数保存了i变量,这个i变量不会变。它的作用域在这个返回的匿名函数。此时i为1.

剩下同理,函数保存了变量的值。所以这次执行结果会按照我们开始设想的那样输出:
Alt text

这里用闭包保存变量的值。

posted @ 2014-09-05 18:53  xiquwugou  阅读(274)  评论(0编辑  收藏  举报