执行上下文

一、当JS在运行代码的时候,会产生三种执行上下文:

1、全局执行上下文

2、函数执行上下文

3、eval执行上下文

每个执行的上下文都有三个重要的属性:

1、变量对象(VO):包含变量,函数声明,函数形参,该属性只能在全局上下文中访问

2、作用域链:(JS采用词法作用域,也就是说变量在定义的时候就决定了)

3、this指针

对于以下代码:

var a = 10
function foo(i) {
  var b = 20
}
foo()
在执行栈中,有两个执行上下文:函数执行上下文和全局执行上下文;
对于全局执行上下文:VO是这样的
globalContext.VO === globe
globalContext.VO = {
    a: undefined,
   foo: <Function>,
}
对于函数执行上下文
fooContext.VO === foo.AO
fooContext.AO {
    i: undefined,
    b: undefined,
    arguments: <>
}
//arguments是函数独有的对象,箭头函数没有,该对象是一个伪数组,有length且可以通过下标访问元素。该对象的callee属性代表函数本身,caller代表函数的调用者。
作用域链scope:可以看成是包含自身变量对象和父级变量对象的列表,可以通过属性[[Scope]]查找父级变量对象。

所以在变量提升出现undefine的解释为:在生成执行上下文的时候,分为两个阶段,创建阶段生成变量对象VO,并在栈中开辟空间,给变量赋值undefined,所以代码执行阶段,可以直接调用。

而let声明的变量不能提前使用因为,let申明了变量,但并未对其进行赋值,所以临时性死区导致其不能被提前调用。

!注:对于非匿名立即执行函数,js解释器会生成一个辅助的特定对象,然后将名称作为这个对象的属性,因此函数内部才可以访问到外部变量,但是访问的值是只读的,不能对其进行赋值.

二、代码执行过程

1、创建全局执行上下文,从上到下执行全局上下文。

2、遇到函数,函数的执行上下文(callee)被push到执行栈的顶层

3、函数执行上下文被激活,开始执行函数,caller被挂起

4、函数执行完成,callee被移除执行栈 ,控制权交换全局上下文(caller),继续执行。

posted @ 2022-02-17 15:31  大坏坏狼  阅读(85)  评论(0)    收藏  举报