zoukankan      html  css  js  c++  java
  • JS关于setTimeout()与for(){}循环之间的纠缠不清

    问题写法

    for(var i = 1; i <= 5; i++) {
        setTimeout( function(){
            console.log(i);
        },i*1000);
    }
    console.log(i);
    // 先输出环境运行产生的一个6,每隔1s,再输出一个6,连续输出5个6
    
    • 解析:
      • 此处的i是由var定义在全局作用域内,输出值i属于全局作用域的值
      • setTimeout()函数运行机制是,等全局环境运行完成后,再运行回调函数
      • 因此,i的终值是都是全局变量i的值
      • 因为回调函数并不是随着环境一起运行的,而是等到环境函数运行完成后再集中运行的
      • 因此,五次循环相当于一起执行五次setTimeout()函数
      • 所以累加的秒数就相当于,每隔一秒执行一次

    let定义写法

    for(let i = 1; i <= 5; i++) {
        setTimeout( function(){
            console.log(i);
        },i*1000);
    }
    console.log(i);
    // 先输出i未定义,再每隔1s输出累加值
    
    • 解析:
      • 此处的i是由let定义在块级作用域内,输出值i属于块级作用域的值
      • 因此当i值出现变化时,是属于内部作用域的变化
      • 而setTimeout()函数运行机制是,等环境运行完成后,再运行回调函数
      • 因此,当i值出现变化时,已经没有环境程序在运行了
      • 所以,此时for循环是跟着setTimeout()函数运行的
      • 因此,i的输出值是for循环的累加值

    立即函数写法

    for(var i = 1; i <= 5; i++) {
        (function(i){
            setTimeout( function(){
                console.log(i);
            },i*1000);
        })(i);
    }
    console.log(i);
    // 先输出i未定义,再每隔1s输出累加值
    
    • 解析:
      • 此处的i是由var定义在全局作用域内,输出值i属于全局作用域的值
      • 虽然,setTimeout()函数运行机制是,等全局环境运行完成后,再运行回调函数
      • 但是,每次的for循环运行时,内部的立即函数都会执行
      • 而且,i的值会由形参i传入到setTimeout()函数内部
      • 从而形成关于i的私有作用域
      • 因此此时的setTimeout()函数是和环境程序一起行动的
      • 而最外围的i的输出没有时延,因此会先输出

    闭包函数写法

    for (var i = 1; i <= 5; i++) {
    	setTimeout(function(i) {
    		return function(){
    			console.log(i);
    		}
    	}(i), i*1000);
    }
    console.log(i);
    // 先输出i未定义,再每隔1s输出累加值
    
    • 解析:
      • 此处的i是由var定义在全局作用域内,输出值i属于全局作用域的值
      • setTimeout()函数运行机制是,等全局环境运行完成后,再运行回调函数
      • 而此处的闭包写法,已然将for循环中i的变量值通过形参i保存于return机制中
      • 形成私有作用域
      • 待setTimeout()进行回调函数运行时,i将输出私域内的累加值

    错误写法

    for(var i = 1; i <= 5; i++) {
        setTimeout(function(i){
            console.log(i);
        }(i),i*1000);
    }
    console.log(i);
    
    • 解析:
      • 此处的setTimeout()函数内的回调函数
      • 在主程序运行时,已经随着主程序一起执行完毕
      • 待setTimeout()异步运行时,已无回调函数可用
  • 相关阅读:
    NetCore入门篇:(十)Net Core项目使用Cookies
    NetCore入门篇:(九)Net Core项目使用Session及用Redis做分布式
    NetCore入门篇:(八)Net Core项目使用Controller之三
    NetCore入门篇:(七)Net Core项目使用Controller之二
    NetCore入门篇:(六)Net Core项目使用Controller之一
    NetCore入门篇:(五)Net Core项目使用静态文件
    NetCore入门篇:(四)Net Core项目启动文件Startup
    NetCore入门篇:(三)Net Core项目Nuget及Bower包管理
    NetCore入门篇:(二)Net Core项目创建
    NetCore入门篇:(一)Net Core环境安装
  • 原文地址:https://www.cnblogs.com/SharkJiao/p/13552430.html
Copyright © 2011-2022 走看看