作者回复: 很好,这个答案大家可以参考下
作者回复: 执行函数时才有进行编译,抽象语法树(AST)在进入函数阶段就生成了,并且函数内部作用域是已经明确了,所以进入块级作用域不会有编译过程,只不过通过let或者const声明的变量会在进入块级作用域的时被创建,但是在该变量没有赋值之前,引用该变量JavaScript引擎会抛出错误---这就是“暂时性死区”
作者回复: 对的,你的理解没错
函数只会在第一次执行的时候被编译,所以编译时变量环境和词法环境最顶层数据已经确定了。
当执行到块级作用域的时候,块级作用域中通过let和const申明的变量会被追加到词法环境中,当这个块执行结束之后,追加到词法作用域的内容又会销毁掉。
作者回复: 暂时性死去是语法规定的,也就是说虽然通过let声明的变量已经在词法环境中了,但是在没有赋值之前,访问该变量JavaScript引擎就会抛出一个错误。
作者回复: 赞
作者回复: 使用let/const声明的变量,伴随着词法环境被创建,但只有在变量的词法绑定(LexicalBinding)已经被求值运算后,才能够被访问。
你也可以在let b声明之前断点下,看看scope中的值有没有,你会看scope中的值已经存在了。
作者回复: 对的,第一个分析的没问题
第二个let不会产生变量提升
作者回复: 还要考虑暂时性死区的问题,这个我在文中没介绍,可以自行搜索下。可以参考下其它评论。
作者回复: 暂时性死区,你可以参考下其它评论
作者回复: 对的,你的分析没问题,这两行都会报错
作者回复: 变量初始化和创建再上上一节《变量提升:JavaScript代码是按顺序执行的吗?》中已经讲过了,
我们将到了一个变量编译阶段和执行阶段分别要做那些事情。
这一节主要是将var和let的区别以及底层实现机制的,我看你的疑问是下面这个问题:
function test(){
console.log(a)
let a = 7;
}
test()
执行test的时候,编译阶段a已经在内存中,为什么提前访问不了?
这主要是因为V8虚拟机做了限制,虽然a在内存中,但是当你在let a 之前访问a时,根据ECMAScript定义,虚拟机会阻止的访问!
如果你还有其它具体的问题,欢迎继续提出!