原来,我真的不懂let

作为一个JS初学者,我一直是对ES6各种奇妙的语法带有一丝敬畏的.从var-let,promise,解构,到各种神奇的const骚操作,一直让我感觉ES6用的好的人似乎代码中包含着魔力.

今天在看知乎的时候,我发现了方方提的这样一个问题.
https://www.zhihu.com/question/62966713

问题
问题

x
lex x=x
x
let x

第一个第二个的报错自然好理解,不用多废话.但是第三个和第四个就比较诡异了:如果我调用x,那么会提示x未被定义.但是当我想定义x的时候,x又是已经被声明的?

我发现以我的知识无法理解这个问题.

于是看了一下底下的回答:


title
title

贺老的回答已经指出了问题的关键,但是对于我来说,还是理解的比较困难.
然后看了孙北吉 的回答,感觉自己又懂了一些.最后看了方方的博客,感觉自己似乎还是不太懂.于是尝试自己解释并总结一下.

问题的本质就是JS 变量的「创建create、初始化initialize 和赋值assign」.

在第一个报错直接输入x中,JS做了这样的操作:

在当前环境中进行查找x.
因为是全局环境   ,直接抛出一个 ReferenceError,提示x不存在.

在第二个报错lex x=x中:

lex x=x是一个RHS查询,它会直接进行值的查找并通知引擎做这些事:
 
 1. 创建变量.
 2. 开始执行代码(到现在为止,还未初始化)
 3. 将x进行初始化为undefined.(这个操作并不是赋值,仅仅是初始化)
 4. 执行RHS操作将x赋值给x.(这才是赋值操作)
因为我们的初始化语句与赋值语句是同一句,所以我们的let x=x同时执行了3\4步的操作.但是这里就出现了一个问题,这一句话是错的.在报错的同时,第三步已经执行完成了,而第四步就没有办法进行,在报错的同时也取消掉了第三步进行的对x的初始化.也就是说这个值已经进行了变量创建,但是并未初始化.所以:

在第三个报错x中:

这个变量x在当前的环境中已经存在(已经被创建过),但是事实上这个变量并未进行初始化,也就无法进行各种操作以及访问了.此时就会抛出一个Reference Error.

在第四个报错let x中:

在此处我们尝试着进行了let x,实际上执行的就是第二个报错的第一步-创建变量.但是变量已经被创建,所以会提示变量已存在.就这样,我们得到了一个已经被创建但是并未被声明且无法被访问的变量.

这就是我的理解,如果有错误,还请看到这里的你指正.谢谢.

So.Because JavaScript.

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容