1.从编译到执行,js做了什么?
编译阶段,js做了三件事情:
1)词法分析
将代码分解成有意义的代码块
2)抽象语法树(AST)
将词法单元转换成嵌套的由程序语法组成的树。
3)机器指令
将AST转换成机器可以执行的指令,等待执行。
执行代码。
2.作用域
1)js引擎:用来编译和执行整个过程。
2)作用域:收集变量、控制变量的访问权限。
3)编译器:执行词法分析等编译过程
词法作用域是由代码位置决定的,每一个函数和块作用域都会形成一个作用域气泡,最后会形成作用域链,引擎执行代码时会由内而外查找变量。
块作用域:
除了函数作用域会形成作用域气泡,块作用域也可以,但是在块作用域中用var声明变量,var不会被绑定在当前块作用域,但是let可以。
3.提升
var变量声明和函数声明都会在编译阶段将声明提升到作用域的顶部,也是一个分配作用域的过程。
4.闭包
函数能够记住并访问当前词法作用域,就算该函数不在词法作用域下执行。这就是闭包。
for(var i=0;i<5;i++){
setTimeout(()=>{
console.log(i)
},1000)
}
闭包改进后:
for(var i=0;i<5;i++){
(function(){
setTimeout(()=>{
console.log(i)
},1000)
})(i)
}
或
for(let i=0;i<5;i++){
setTimeout(()=>{
console.log(i)
},1000)
}