JS中的执行上下文
**概念:**当控制器转入可执行代码的时候就会进入一个执行上下文,可以理解为当前代码的运行环境,会形成一个作用域,JS的运行环境的大致分为三种:
全局环境:代码运行起来首先进入该环境
函数环境:函数被执行的时候进入当前函数中执行代码
eval()
处理方法:JS引擎用堆栈的方式来处理程序执行过程中的上下文,栈底是全局上下文,而栈顶是正在执行的上下文,栈顶的执行完毕弹出,遇到return时直接出栈
上下文的建立:
时机:函数执行上下文是在函数被调用,函数体还没执行时创建
创建阶段:建立变量、函数、建立作用域链、确定this的值等
执行阶段:为变量赋值、执行代码
执行上下文主要包括:变量对象、作用域链、this
执行上下文主要包括:变量对象、作用域链、this
变量对象
在执行上下文中会创建一个叫变量对象的特殊对象。基础数据类型往往保存在变量对象中。变量对象中包括函数的所有参数,以及用function声明的函数声明和用var声明的变量的声明(可以去了解一下变量提升机制)
变量对象创建:
1、先获取函数的参数和值
2、再获取function声明的函数的声明,会以函数名创建一个属性,属性值是指向该函数所在内存地址的引用,遇到同名就覆盖
3、再依次获取当前上下文中的变量声明,创建一个属性,属性名称是变量名,值是undefined,遇到同名跳过
注意:
1、let和const声明的变量是在上下文执行阶段执行的,避免变量提升带来的麻烦。
2、上下文创建阶段同名变量不会覆盖,但执行阶段会
3、全局上下文的变量对象就是window对象,且不会变成活动对象
作用域链
作用域链是由当前执行环境和上层执行环境的一系列变量对象组成的,保证当前执行环境对符合访问权限的变量和函数的有序访问
闭包会不会导致作用域链的变化?
函数调用栈是在函数执行时产生的,而作用域是在编译阶段就已经确定了,虽然作用域链是在函数执行是生成的,但它并不会在执行时改变,所以闭包不会导致作用域链的变化
有关this的问题请看我的另一篇文章、、、