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

let和var的一个问题

原代码来自ruan老师ES6书,作为var和let对比的说明。

 

我特地去SF社区问了下,得到了一些大佬们很好的回答。我这里总结一下。

 

1. 必须记住的两点:函数作用域是声明时确定的,函数内的值是执行时确定的!

所以执行时去确定i,注意function函数参数列表里没有传入i的值,会去外层作用域找,此时i已经在遍历完变成了10。

 

2. 变量i是var命令声明的,在全局范围内都有效。这跟C语言中的for循环里的临时变量i很大不同了 =-=。

每一次循环,变量i的值都会发生改变,而循环内被赋给数组a的函数内部的console.log(i),里面的i指向的就是全局的i。也就是说,所有数组a的成员里面的i,指向的都是同一个i,而函数内的值是执行时确定的,导致运行时输出的是最后一轮的i的值,也就是 10。

3.如果使用let,声明的变量仅在块级作用域内有效,最后输出的是 6

var a = [];
for (let i = 0; i < 10; i++) {
  a[i] = function () {
    console.log(i);
  };
}
a[6](); // 6

上面代码中,变量i是let声明的,当前的i只在本轮循环有效,所以每一次循环的i其实都是一个新的变量,所以最后输出的是6。那么我们可能会问,如果每一轮循环的变量i都是重新声明的,那它怎么知道上一轮循环的值(i自加的计算),从而计算出本轮循环的值?这是因为 JavaScript 引擎内部会记住上一轮循环的值,初始化本轮的变量i时,就在上一轮循环的基础上进行计算。

 然后解决方案是:

既然函数作用域是声明时确定的,函数内的值是执行时确定的,那么我可以声明一个匿名函数,让他每次i循环时就立即自执行,对了,就是闭包。

for ( var i=0; i<10; i++ ) {

(function(i){
a[i] = function () {
console.log(i)
}
})(i)
}

这里有一个匿名自执行的函数 在i循环的时候就取到了当前的i的值

 

然后深入的话,可以看这个系列的 http://www.cnblogs.com/wangfupeng1988/p/3977924.html,很系统的说明了。

我在sf问的问题:https://segmentfault.com/q/1010000012229085?_ea=2917221

转载于:https://www.cnblogs.com/zhangmingzhao/p/7930057.html

相关文章:

  • aix 查看占用内存高的进程
  • WIN7 U盘安装
  • [完美]原生JS获取浏览器版本判断--支持Edge,IE,Chrome,Firefox,Opera,Safari,以及各种使用Chrome和IE混合内核的浏览器...
  • MongoDB(课时10 数组)
  • vue+vuex+axios+echarts画一个动态更新的中国地图
  • 你绝不能错过的效率神器 —— Alfred
  • Clojure CLR 入门
  • 基于Metronic的Bootstrap开发框架经验总结(8)--框架功能总体界面介绍
  • 配置ssh免密码登陆配置和ssh原理
  • 基于MVC4+EasyUI的Web开发框架经验总结(11)--使用Bundles处理简化页面代码
  • zxing二维码的生成与解码(C#)
  • DelphiMVC拦截器介绍
  • MySQL主键添加/删除
  • 成为优秀Java程序员的10个要点
  • 刚刚!没参加饭局的马云用iDST的语音技术买了张地铁票,竟然没说唤醒词
  • -------------------- 第二讲-------- 第一节------在此给出链表的基本操作
  • ERLANG 网工修炼笔记 ---- UDP
  • Fabric架构演变之路
  • HashMap ConcurrentHashMap
  • Java IO学习笔记一
  • Less 日常用法
  • MQ框架的比较
  • Netty 框架总结「ChannelHandler 及 EventLoop」
  • node和express搭建代理服务器(源码)
  • vue中实现单选
  • 官方新出的 Kotlin 扩展库 KTX,到底帮你干了什么?
  • 缓存与缓冲
  • 那些被忽略的 JavaScript 数组方法细节
  • 前端代码风格自动化系列(二)之Commitlint
  • 一个SAP顾问在美国的这些年
  • 关于Kubernetes Dashboard漏洞CVE-2018-18264的修复公告
  • #[Composer学习笔记]Part1:安装composer并通过composer创建一个项目
  • #define用法
  • #gStore-weekly | gStore最新版本1.0之三角形计数函数的使用
  • #QT(TCP网络编程-服务端)
  • ( )的作用是将计算机中的信息传送给用户,计算机应用基础 吉大15春学期《计算机应用基础》在线作业二及答案...
  • (17)Hive ——MR任务的map与reduce个数由什么决定?
  • (delphi11最新学习资料) Object Pascal 学习笔记---第2章第五节(日期和时间)
  • (function(){})()的分步解析
  • (Redis使用系列) Springboot 使用Redis+Session实现Session共享 ,简单的单点登录 五
  • (翻译)terry crowley: 写给程序员
  • (学习日记)2024.01.19
  • ***微信公众号支付+微信H5支付+微信扫码支付+小程序支付+APP微信支付解决方案总结...
  • .NET : 在VS2008中计算代码度量值
  • .Net 6.0 处理跨域的方式
  • .Net Web项目创建比较不错的参考文章
  • .NET 中使用 TaskCompletionSource 作为线程同步互斥或异步操作的事件
  • .NET学习全景图
  • .NET应用架构设计:原则、模式与实践 目录预览
  • .net中生成excel后调整宽度
  • //解决validator验证插件多个name相同只验证第一的问题
  • @Autowired多个相同类型bean装配问题
  • @ResponseBody
  • [ 隧道技术 ] 反弹shell的集中常见方式(二)bash反弹shell
  • [Android]使用Git将项目提交到GitHub