JS:执行上下文(*****高阶底层五颗星)
1.执行上下文
程序的本质是状态机,换句话说,程序的执行就做两件事,就是对数据的都和写。
从程序的角度出发,当需要读写一个变量时,程序去哪里找这个变量呢?
执行上下文,执行上下文也就是程序查找变量的空间的一个抽象。
执行上下文就是程序读写数据时查找变量的地方,那么这个赌坊具体什么情况呢?
对于JS而言,读写变量的情况可以细分一下:
- 全局读写变量
- 函数内读写变量
- eval
执行上下文也可以分为两种:全局执行上下文和函数执行上下文。这两个执行上下文是有点差别的。
2.全局执行上下文
执行上下文从广义上可以分为两块:Lexical Environment和This Binding
1.Lexical Environment
组成:
- 全局对象:全局变量var和顶级函数会加在window全局对象
- 全局scope:存放顶级的let,const,class等边
- outer:在全局执行上下文中outer为null
全局对象:
- 浏览器环境下是window对象
2.This Binding
当使用this的时候,其实就是This Binding这个区域存储的值。
对于全局执行上下文(GC),This Binding指向全局对象,在浏览器环境下是window。
函数的this被改取决于他的执行上下文的方式(如:call/apply/bind/),进而修改This Binding的值。
3.执行上下文创建流程:
执行上下文的作用是为程序提供查找变量的地方,因此,执行上下文的常见流程就是将程序中的变量声明进行处理,存储在执行上下文里。
注意:执行上下文的创建是在整个代码执行之前创建完成的,代码只有在执上下文创建完成之后才有能力去执行代码时找到变量。所以注意执行前(AST->执行上下文创建)和执行时。
可以简单的将其划分为下面几个步骤:
- 处理声明
- 检查重复定义
- 创建绑定
1.处理声明
- 找到所有的全局中的var声明,找到所有的顶级全局函数声明(注意和函数表达式进行区分),将其记录在全局对象中(浏览器环境下全局对象就是window)。
- 找到顶级的(全局环境下)let,const,class记录在全局的scope。
<script> var a=1 //全局var声明,放在全局对象window中 function fn(){//顶级函数声明,放在全局对象window中 } if(true){ function fn1(){//非顶级函数申明 } } (function fn2(){//函数表达式,不是函数声明,函数声明必须是以function开头。 }) </script>
2.检查重复定义
这一步比较简单就是:(只会检查全局scope或全局scope和全局对象是否重复,不会检查全局对象内部是否有重复)
看全局scope有无重复声明
剩余60%内容,订阅专栏后可继续查看/也可单篇购买
前端面试题 文章被收录于专栏
前端面试的一些常问问题、问题的具体实现(可直接运行)以及底层原理