题目一:
-
js是怎么执行的?
就是一个调用栈的过程,执行js的时候进行入栈和出栈的过程,栈底始终是全局执行上下文(window或global);
-
那每一个执行上下文中有哪些模块呢?
2.1 :变量环境
变量环境中存放var声明的变量,每进行一次入栈操作,都会为这个入栈函数分配一片环境变量存放var声明的变量。
2.2:词法环境(栈的数据结构)
-
词法环境存放let和const声明的变量或常量,栈底存放的是外层let或const变量 var1,遇到for等使用let或const再将let或const声明的var2变量压栈。
-
for循环执行完后var2出栈,函数执行完后var1出栈。
示例:
function foo(){
var a = 1
let b = 2
{
let b = 3
var c = 4
let d = 5
console.log(a)
console.log(b)
}
console.log(b)
console.log(c)
console.log(d)
}
foo()
2.3:this
2.4:outer
题目二:
-
var声明的变量会有变量声明提升,起提升后初始化默认赋值为undefined
-
思考:那let和const声明的变量在块级作用域内会提升吗?
2.1:其实应该是会的,如“你不知道的javascript”上卷中说到,在语言的词法分析阶段,就可以会变量做声明提升的优化,减少编译和执行时的工作量,达到性能优化的效果。
2.2:那为什么在声明前调用let或const变量会报(TDZ)错误呢?
2.3:因为使用let和const声明的变量不会在变量声明提升是初始化复制undefined
2.4:思考?
既然let和const声明的变量在提升后没有赋值undefined,这时候let和const声明的变量在内存地址中存的是什么?
答案一:是不是什么也没存
答案二:上次使用这片内存,但已经没有被引用的数据。
思考:那这时候我们把这些数据读出来合适吗?
如果读出来了,那读出来的是什么数据呢?js是否能识别(js读取不同的类型的数据,是有不同的识别机制的,比如读取的对象,那对象的内存地址前三位都必须为0)
情况1: 如果数据不符合js数据存储的规范,那读出来的数据是不是就紊乱了?
情况2: 如果符合js存储数据的规范,那也会导致数据不对。