首先在JS执行代码前,会先进行预编译处理,也就是对代码中的各个变量和函数抽取出来,开辟一个内存空间,但不进行任何的赋值操作,其中函数表达式在预处理阶段不会被声明,只有个underfind,这也能够解释如果提前调用函数表达式,则会报错,同理,其他的普通变量在赋值前被调用也会出现underfind的情况,在执行阶段时,词法环境中的预编译变量会随着代码的执行变化而变化
接下来就是代码执行的具体过程,其中JS引擎会在代码正式执行前,对变量和函数进行提升,把声明变量和声明函数提升至代码执行的顶端,再依次往下执行,如果变量是未声明的自由变量,那么自由变量会在创建自身的作用域链中进行寻找,未找到则报错,而未声明的函数比方说具名或匿名函数表达式,则会通过变量访问进行提升,此外,变量命名出现冲突时,需遵守函数优先,后声明的变量覆盖前面声明的变量等原则
补充一下:函数作用域内的变量,在函数外无法访问,作用域隔离变量的作用。在正常写代码时要遵守先声明变量后使用的原则