一、执行上下文
    js中有三种执行上下文
    (1)全局执行上下文,只有一个,浏览器中全局对象指向window,this指向window
    (2)函数执行上下文,每当函数执行时,会产生新的函数执行上下文,this绑定有不同方法。
    (3)eval执行上下文,不推荐使用eval,严格模式下,eval有自己作用域
    二、执行栈
    又称调用栈,用于储存执行上下文,具有LIFO结构,先进后出。
    js代码执行时,会创建全局执行上下文,放入调用栈中,调用函数时,函数执行上下文会排在栈顶,函数运行结束后,其执行上下文会出栈,将上下文控制权交给栈顶的上下文。

    三、执行上下文的创建
    分为两个阶段
    (1)创建阶段
    1、this绑定
    a、全局执行上下文,this绑定到window对象
    b、函数执行上下文,有不同绑定方式,之后详细分类。
    2、创建词法环境
    词法环境分为两种:
    (1)全局执行上下文词法环境,包含了window全局对象、js内置对象与方法以及用户定义的变量与方法。
    (2)包含了用户在函数中定义的变量与方法,以及arguments对象。
    a、环境记录,储存含函数与变量实际位置(记录了let和const声明的变量,但是未初始化(uninitialized)这就是为什么es6中为存在暂时性死区。
    b、对外部环境的引用outter:全局执行上下文的outter为null。(这个跟作用域有什么关系?)
    3、创建变量环境
    变量环境也是一种词法环境,具有词法环境所有属性,会记录var声明的变量,变量会初始化,值为undefined。
    词法环境与变量环境的区别在于,词法环境会绑定函数声明、const和let声明的变量绑定。而变量环境仅会绑定var声明的变量
    (2)执行阶段
    完成所有变量的分配,最后执行代码