zoukankan      html  css  js  c++  java
  • 闭包与循环

        	// 来自 《你不知道的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 的效果
    	 */
    	
    
    
  • 相关阅读:
    第二次冲刺第六天
    第二次冲刺第五天
    第二次冲刺第四天
    Java多线程学习篇(三)Lock
    Java多线程学习篇(二)synchronized
    Java多线程学习篇(一)
    codeforces 895D
    模运算的乘法逆元
    codeforces 889B
    codeforces 878C
  • 原文地址:https://www.cnblogs.com/lcysgsg/p/6680231.html
Copyright © 2011-2022 走看看