文档章节

我用了两个月的时间才理解 let

FeanLau
 FeanLau
发布于 2017/09/03 14:16
字数 849
阅读 21
收藏 0
点赞 0
评论 0

当然不是说用完整的两个月时间来理解 let,而是零零碎碎地理解,同时我还要想着怎么写出一篇文章把这个事情说清楚。

在 let 刚出来的时候,我就「以为」我理解了 let。然鹅在过去的两个月里,我对 let 的理解发生了一波三折的变化。

我写这篇文章,是希望我的学习过程,能对你自学有帮助。

初识 let

跟很多人一样,我第一次了解 let 的特性是从 MDN 的文档:

我得到的信息有这么几条:

  • let 声明的变量的作用域是块级的;
  • let 不能重复声明已存在的变量;
  • let 有暂时死区,不会被提升。

大部分人应该都是这么认为的,我也是这么理解的。

第一次质疑

我第一次质疑我的理解是在遇到 for 循环的时候,代码如下。

// 代码段1
var liList = document.querySelectorAll('li') // 共5个li
for( var i=0; i<liList.length; i++){
  liList[i].onclick = function(){
    console.log(i)
  }
}

大家都知道依次点击 li 会打印出 5 个 5。如果把 var i 改成 let i,就会分别打印出 0、1、2、3、4

// 代码段2
var liList = document.querySelectorAll('li') // 共5个li
for( let i=0; i<liList.length; i++){
  liList[i].onclick = function(){
    console.log(i)
  }
}

然而,用我之前的知识来理解这个代码是不能自圆其说的。因为代码中依然只声明了一个 i,在 for 循环结束后,i 的值还是会变成 5 才对。

这说明我的理解有误。

于是我去看 MDN 的例子,发现鸡贼的 MDN 巧妙地避开了这个问题,它的例子是这样的:

你看 MDN 的例子,在每次循环的时候用 let j 保留的 i 的值,所以在 i 变化的时候,j 并不会变化。而console.log 的是 j,所以不会出现 5 个 5。

为什么 MDN 要故意声明一个 j 呢,为什么不直接用 i 呢?

我猜测 MDN 为了简化知识,隐瞒了什么。

于是我去看了看 ES 文档,其中的 13.7.4.7 章节 清楚地说明了个中缘由,但是由于说得太清楚了,很多人都看不下去,不信你可以试试。

我说一下我的理解:

  1. for( let i = 0; i< 5; i++) 这句话的圆括号之间,有一个隐藏的作用域
  2. for( let i = 0; i< 5; i++) { 循环体 } 在每次执行循环体之前,JS 引擎会把 i 在循环体的上下文中重新声明及初始化一次。
  3. 其他细节就不说了,太细碎了

也就是说上面的代码段2可以近似近似近似地理解为

// 代码段3
var liList = document.querySelectorAll('li') // 共5个li
for( let i=0; i<liList.length; i++){
  let i = 隐藏作用域中的i // 看这里看这里看这里
  liList[i].onclick = function(){
    console.log(i)
  }
}

那样的话,5 次循环,就会有 5 个不同的 i,console.log 出来的 i 当然也是不同的值。

再加上隐藏作用域里的 i,一共有 6 个 i。

这就是 MDN 加那句 let j = i 的原因:方便新人理解。

总得来说就是 let/const 在与 for 一起用时,会有一个 perIterationBindings 的概念(一种语法糖)。

从此之后,我就开始怀疑我对 let 的所有理解了。

 

本文转载自:https://zhuanlan.zhihu.com/p/28140450

共有 人打赏支持
FeanLau
粉丝 3
博文 201
码字总数 129363
作品 0
浦东
程序员
Let's Encrypt 使用教程,免费的SSL证书,让你的网站拥抱 HTTPS

这篇文章主要讲的就是如何让自己的网站免费从HTTP升级为HTTPS,使用的是 Let's Encrypt的证书。实际上也就是一个Let's Encrypt 免费证书获取教程 。 为什么要上HTTPS,说一个小故事。 从前有...

yzy121403725 ⋅ 2017/11/14 ⋅ 0

从菜鸟到架构师(十三)

随着我经验的增长和技术的提高,我已经不满足于现在的工资,公司的工资在业界算是比较低的。 我向伟哥提出过离职的申请,当时想的是跳槽随便都能涨工资。当时和伟哥谈了很久,他说:“我们公...

lynnlovemin ⋅ 2017/04/19 ⋅ 0

smart-socket v1.3.0,不安分的搅局者

smart-socket自发布以来,得到了很多朋友的认可,同时也伴随着的不少的质疑。大部分的质疑是无实际论据支撑的,就是看你不爽,就是你想喷你的项目。对于这样的“朋友”,现在很高兴的通知你们...

三刀蜀黍 ⋅ 01/23 ⋅ 0

Java一般要学多久?如是我闻

其实学java一般要多久?因人而异,有些人资质好,头脑聪明几个月就能学会,有些人天生愚钝,理解能力差,不过勤能补拙,只是时间相对长点 要坚持住。不过java相对于C,C++java而言,java无疑简...

ToEnd ⋅ 2017/12/09 ⋅ 0

碎片化严重 Android 6.0 升级率不到 0.3%

Android系统的碎片化是谷歌最头疼的事情,而每次谷歌发布Android系统的新版本,似乎都要面对无止境的“更新”问题,这时谷歌才发现,居然还有不少人正在使用几年前版本的系统。目前一个非常有...

oschina ⋅ 2015/12/04 ⋅ 40

浅聊这2各月的学习

从今年的7月份学校放暑假,到如今马上又要开学,忽然间2个月的时间已匆匆过去。这两天也没有做出什么具有效率成果的事情,编写一文章做点总结吧。 当暑假即将来临的那会,我已经在着急忙忙的...

wewoor ⋅ 2012/09/06 ⋅ 0

为了项目上线而加班,真有必要吗?

大家都知道:软件项目的加班可能真是有百害而无一利,但总还有些时候,有些人有侥幸心理,或是现实情况实在无法让步,比如项目必须在某个日期上线; 在这些情况下,应该跟团队沟通些什么?Q...

oschina ⋅ 2013/08/08 ⋅ 83

开始DBA之路二

其实我一直都想从事IT这个行业的工作的。 但是在大学的时候,我虽然业余时间会关注一些这个行业的消息,但是主要精力还是放在了所学专业和吃喝玩乐上面(主要是吃喝玩乐),但是,本专业学的...

韩呵呵哒 ⋅ 2016/03/04 ⋅ 0

IT连创业系列:说说苹果商店AppStore上架App应用前后遇到的那些神坑

前言: IT连创业的这个系列,又隔空了一个多月了。 不知道为什么,最近写文的冲动感下降了很多,如果不是因为特别忙,大概就因为上了年纪的原因了。 群里关注我创业的朋友,一直都在问,啥时...

路过秋天 ⋅ 2017/11/03 ⋅ 0

惠普发布开源webOS操作系统的首个测试版

在惠普原来宣布开源软件版webOS操作系统几个月之后,惠普周五终于推出了这个平台的测试版。 惠普周五发布了测试版包括两个开发人员环境。第一个是桌面开发环境。这个开发环境以更多的功能和集...

oschina ⋅ 2012/09/01 ⋅ 7

没有更多内容

加载失败,请刷新页面

加载更多

下一页

容器之重命名镜像

使用docker tag命令来重命名镜像名称,先执行help,查看如何使用如下 mjduan@mjduandeMacBook-Pro:~/Docker % docker tag --helpUsage:docker tag SOURCE_IMAGE[:TAG] TARGET_IMAGE[:TA...

汉斯-冯-拉特 ⋅ 20分钟前 ⋅ 0

with 的高级用法

那么 上下文管理器 又是什么呢? 上下文管理器协议包含 __enter__ 和 __exit__ 两个方法。with 语句开始运行时,会在上下文管理器对象上调用 __enter__ 方法。with 语句运行结束后,会在上下...

阿豪boy ⋅ 39分钟前 ⋅ 0

使用 jsoup 模拟登录 urp 教务系统

需要的 jsoup 相关 jar包:https://www.lanzous.com/i1abckj 1、首先打开教务系统的登录页面,F12 开启浏览器调试,注意一下 Request Headers 一栏的 Cookie 选项,我们一会需要拿这个 Cook...

大灰狼时间 ⋅ 39分钟前 ⋅ 0

关于线程的创建

转自自己的笔记: http://note.youdao.com/noteshare?id=87584d4874acdeaf4aa027bdc9cb7324&sub=B49E8956E145476191C3FD1E4AB40DFA 1.创建线程的方法 Java使用Thread类代表线程,所有的线程对......

MarinJ_Shao ⋅ 51分钟前 ⋅ 0

工厂模式学习

1. 参考资料 工厂模式-伯乐在线 三种工厂-思否 深入理解工厂模式 2. 知识点理解 2.1 java三种工厂 简单工厂 工厂模式 抽象工厂 2.2 异同点 逐级复杂 简单工厂通过构造时传入的标识来生产产品...

liuyan_lc ⋅ 今天 ⋅ 0

Java NIO

1.目录 Java IO的历史 Java NIO之Channel Java NIO之Buffer Java NIO之Selector Java NIO之文件处理 Java NIO之Charset Java 可扩展IO 2.简介 “IO的历史”讲述了Java IO API从开始到现在的发...

士别三日 ⋅ 今天 ⋅ 0

[Err] ORA-24344: success with compilation error

从txt文本复制出创建function的脚本,直接执行,然后报错:[Err] ORA-24344: success with compilation error。 突然发现脚本的关键字,居然不是高亮显示。 然后我把脚本前面的空格去掉,执行...

wenzhizhon ⋅ 今天 ⋅ 0

Spring Security授权过程

前言 本文是接上一章Spring Security认证过程进一步分析Spring Security用户名密码登录授权是如何实现得; 类图 调试过程 使用debug方式启动https://github.com/longfeizheng/logback该项目,...

hutaishi ⋅ 今天 ⋅ 0

HAProxy基于KeepAlived实现Web高可用及动静分离

前言 软件负载均衡一般通过两种方式来实现: 基于操作系统的软负载实现 基于第三方应用的软负载实现 LVS是基于Linux操作系统实现的一种软负载,而HAProxy则是基于第三方应用实现的软负载。 ...

寰宇01 ⋅ 今天 ⋅ 0

微软自研处理器的小动作:已经开始移植其他平台的工具链

微软将 Windows 10 、Linux 以及工具链如 C/C++ 和 .NET Core 运行时库、Visual C++ 2017 命令行工具、RyuJIT 编辑器等移植到其自主研发的处理器架构 E2。微软还移植了广泛使用的 LLVM C/C++...

linux-tao ⋅ 今天 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部