闭包与循环

    	// 来自 《你不知道的JavaScript(上卷)》 
		// 5.4 循环和闭包
		// p48-p51页的整理

/**
 *   希望隔特定秒数打印 每个i
 *   但是打印出来的是 5
 *   为什么会是5呢? 
 *   因为 循环的终止条件是 i<5 
 *   而   延迟函数的回调 会在 循环结束时 才执行
 *   所以 输出显示的 i=5 是循环结束时的最终值
 *   ====== 
 *   但为什么偏偏是最终值呢?
 *   因为是 var i;
 *   for(..)中的 var 其实是创建的全局变量
 *   所以看似每个 i 都不同, 实际上整个作用域里只有一个 i
 *   而 延迟函数 又是在 循环结束时 才执行
 *   那延迟函数找到的值自然是整个作用域里最后剩下的 i=5 
 */

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


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


  	/**
  	 * 它需要有自己的变量, 迭代一次存储一次
  	 */
  	
for (var i = 0; i < 5; i++) {
  (function(){
    var j = i; // 写在了 setTimeout 外面,所以 for(..)一次,赋值一次
    setTimeout( function timer(){
      console.log( j ); // 0,1,2,3,4
    }, j*1000);
  })(); 
}


// 可以用传参的方式达到同样的效果
for (var i = 0; i < 5; i++) {
  (function( j ){
    setTimeout( function timer(){
      console.log( j ); // j:0,1,2,3,4  
      console.log( i ); // i:5,5,5,5,5
    }, i*1000); 
    // 看到这里的时间间隔时, 我发现漏了个地方
    // 时间间隔里的 i 很奇怪,它还是每隔一秒出
    // 根据结果来推断, 它并不在 timer()里
    // 也就是 时间间隔 里的变量是属于外部的
    // 很简单.. 没毛病的
    // 但我想岔了... 想了好一会儿...
    
  })( i  ); // 这个是外部的 i
}




for (var i = 0; i < 5; i++) {
    let j = i;  // 每次迭代都会声明,每个迭代都会使用上一个迭代结束时的值来初始化这个变量
    setTimeout( function timer(){
      console.log( j ); // 0,1,2,3,4
    }, j*1000);
}



		// 怕是最简单的写法了
for (let i = 0; i < 5; i++) {
    setTimeout( function timer(){
      console.log( i ); // 0,1,2,3,4
    }, i*1000);
}



	/**
	 *  如果奇怪为什么是每隔一秒才打印 i 的话,看这:
	 *  for 是一瞬间执行完的
	 *  setTimeout 也是
	 *  所以, setTimeout( ... , i*1000 ) 就是 1*1000 2*20000 ~
	 *  在一开始就执行过了
	 *  于是达到了每隔一秒出一个 i 的效果
	 */
	

posted @ 2017-04-09 18:32  lcysgsg  阅读(204)  评论(0编辑  收藏  举报