当前位置: 首页 > news >正文

闭包与循环

        // 来自 《你不知道的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 的效果
     */
    

转载于:https://www.cnblogs.com/lcysgsg/p/6680231.html

相关文章:

  • iOS 字符串 MD5
  • 查看linux源代码的在线网站
  • Android入门:MVC模式(中)
  • Oracle中INSTR函数与SQL Server中CHARINDEX函数
  • 沟通和编程一样,也是一门艺术系列5(沟通的方向)
  • CSS实现Tab布局
  • Spring定时任务的几种实现(转)
  • Android Handler使用
  • django-rest-framework学习之Requests and Responses--2017年4月13日
  • LightOJ1245 Harmonic Number (II)
  • Hnoi-2017 滚粗记
  • 新概念英语(1-3)Sorry, sir
  • open-falcon之judge
  • oaracel 函数_行转列
  • Python图像处理(14):神经网络分类器
  • Angular 响应式表单之下拉框
  • const let
  • Invalidate和postInvalidate的区别
  • JavaScript类型识别
  • mysql innodb 索引使用指南
  • mysql 数据库四种事务隔离级别
  • open-falcon 开发笔记(一):从零开始搭建虚拟服务器和监测环境
  • Puppeteer:浏览器控制器
  • Vue2.x学习三:事件处理生命周期钩子
  • -- 查询加强-- 使用如何where子句进行筛选,% _ like的使用
  • 给github项目添加CI badge
  • 工作踩坑系列——https访问遇到“已阻止载入混合活动内容”
  • 基于组件的设计工作流与界面抽象
  • 坑!为什么View.startAnimation不起作用?
  • 跨域
  • 如何实现 font-size 的响应式
  • 一个普通的 5 年iOS开发者的自我总结,以及5年开发经历和感想!
  • 用mpvue开发微信小程序
  • 源码之下无秘密 ── 做最好的 Netty 源码分析教程
  • 云栖大讲堂Java基础入门(三)- 阿里巴巴Java开发手册介绍
  • 主流的CSS水平和垂直居中技术大全
  • 【干货分享】dos命令大全
  • ​​​​​​​ubuntu16.04 fastreid训练过程
  • ​如何防止网络攻击?
  • !! 2.对十份论文和报告中的关于OpenCV和Android NDK开发的总结
  • # Python csv、xlsx、json、二进制(MP3) 文件读写基本使用
  • # 数论-逆元
  • #我与Java虚拟机的故事#连载13:有这本书就够了
  • $redis-setphp_redis Set命令,php操作Redis Set函数介绍
  • (第27天)Oracle 数据泵转换分区表
  • (第9篇)大数据的的超级应用——数据挖掘-推荐系统
  • (附源码)spring boot基于Java的电影院售票与管理系统毕业设计 011449
  • (附源码)ssm捐赠救助系统 毕业设计 060945
  • (简单有案例)前端实现主题切换、动态换肤的两种简单方式
  • (三分钟了解debug)SLAM研究方向-Debug总结
  • (五)MySQL的备份及恢复
  • (一)认识微服务
  • (转)Oracle 9i 数据库设计指引全集(1)
  • ../depcomp: line 571: exec: g++: not found
  • .net core 6 redis操作类