执行上下文和变量对象

      执行上下文这类概念,就是大佬们说很重要,我等新手菜鸟完全无感的东西。下面是我根据《JS高级程序设计》结合部分大佬的解释整理的相关内容。

一、执行上下文概念

   执行上下文个人理解是当前代码的执行环境,它会形成一个作用域。JavaScript中的运行环境大概包括三种情况。

  • 全局环境:JavaScript代码运行时首先进入
  • 函数环境:当函数被调用执行时进入
  • eval(js执行字符串,问题很多,不建议使用,可忽略)

      在一个JavaScript程序中,必定会产生多个执行上下文。JavaScript引擎会以函数调用栈(call stack)的方式来处理它们。栈底是全局上下文,而栈顶就是当前正在执行的上下文。

       下面结合代码和图解来理解一下函数调用栈的执行。

let text = '全局'

  function f1(){
    let text1 = 'f1'
    function f2() {
      let text2 = 'f2'
      console.log(text2)
    }

    f2()
    console.log(text2)
  }

  f1()

  function f3() {
    let text3 = 'f3'
    console.log(text3)
  }
  f3()

console.log(text)

 

执行上下文和变量对象_第1张图片

 

下面总结一下函数调用栈:

  1. 单线程
  2. 执行中的上下文在栈顶执行,其余在下面等待继续执行
  3. 全局上下文在浏览器关闭时出栈
  4. 某个函数被调用时,新的执行上下文创建。

二、变量对象

我们通过上面的图例也可以很明显的看出,一个执行上下文的完成,分为了创建阶段和执行阶段。

  1. 创建阶段

    在这个阶段中,执行上下文会分别创建变量对象,建立作用域链,以及确定this的指向。

  2. 代码执行阶段

    创建完成之后,就会开始执行代码,这个时候,会完成变量赋值,函数引用,以及执行其他代码。

执行上下文的创建阶段产生了变量对象、作用域链和this指向等一系列难点,我觉得这应该就是执行上下文的重要之处吧。

this指向问题在上篇文章当中已做了详细解释,这里我们主要说一下变量对象。

 

变量对象的创建,依次经历了以下几个过程:

  1. 建立arguments对象。检查当前上下文中的参数,建立该对象下的属性与属性值。

  2. 检查当前上下文的函数声明,也就是使用function关键字声明的函数。在变量对象中以函数名建立一个属性,属性值为指向该函数所在内存地址的引用。如果函数名的属性已经存在,那么该属性将会被新的引用所覆盖。

  3. 检查当前上下文中的变量声明,每找到一个变量声明,就在变量对象中以变量名建立一个属性,属性值为undefined。

发现问题没有!对!变量提升!由变量对象的创建过程可知,function的声明比var、let等变量声明要先进行。

下面给大家看个例子,然后大家根据例子理解一下:


function test() {
    console.log(a);
    console.log(foo());

    var a = 1;
    function foo() {
        return 2;
    }
}

test();

//结果是输出 undefind , 2

下面按照执行顺序解释一下:

function test() {
// 先建立arguments对象,检验有无参数
    function foo() {
        return 2;
    }// 函数定义提升到这里
    var a; // 这里是变量定义,未赋值,为undefind
 // 下面才是按照代码顺序的执行阶段
    console.log(a);
    console.log(foo());
    a = 1;
}

test();

注意看代码注释!理解一下变量对象和变量提升。

你可能感兴趣的:(js基础)