setTimeout 学习闭包

时间:2021-08-19 07:55:34

@(技术笔记)[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 是一个异步执行的函数。函数定义如下:

setTimeout 学习闭包

第一个参数是要执行的方法(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.

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

setTimeout 学习闭包

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