Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

执行栈上下文 #11

Open
xiaochengzi6 opened this issue May 19, 2022 · 0 comments
Open

执行栈上下文 #11

xiaochengzi6 opened this issue May 19, 2022 · 0 comments
Labels
JavaScript JavaScript 语言的学习

Comments

@xiaochengzi6
Copy link
Owner

xiaochengzi6 commented May 19, 2022

执行上下文

执行上下文决定了变量或函数可以访问那些数据,以及行为。

全局上下文是最外层的上下文,每个函数都有其自己的上下文。当代码执行流进入函数时,函数的上下文被推到一个上下文栈上。 在函数执行完之后,上下文栈会弹出该函数上下文,将控制权返还给之前的执行上下文。

执行上下文主要有全局上下文和函数上下文两种(eval()调用内部存在第三种上下文)

执行上下文的特点

  1. 单线程,只在主线程上运行;
  2. 同步执行,从上向下按顺序执行;
  3. 全局上下文只有一个,也就是window对象;
  4. 函数执行上下文没有限制;
  5. 函数每调用一次就会产生一个新的执行上下文环境。

执行上下文栈

用来管理所有的执行上下文,首先是全局代码,所以最先开始初始化的是全局上下文然后将其压入栈中 碰到函数就会创建一个函数上下文并且压入栈中 当栈顶函数上下文执行完闭就会被弹出栈。直到程序结束,弹出全局上下文。

** 变量对象 Vo **

每个上下文都有一个关联的变量对象 这个上下文中定义的所有变量和函数都存在于这个对象上

** 活动对象 Ao **

函数上下文中活动对象去用作变量对象。最初只有一个定义变量 arguments 。未进入执行阶段之前,变量对象(VO)中的属性都不能访问!但是进入执行阶段之后,变量对象(VO)转变为了活动对象(AO),里面的属性都能被访问了,然后开始进行执行阶段的操作。

执行过程

执行上下文的生命周期分为三个阶段

在es6 环境中

  1. 创建阶段

    • 确定this的值, 也就是绑定this

      主要是介绍这两种

      • 全局执行上下文中 this 指向 window
      • 函数全局上下文中 this 是由函数的调用方式决定的
    • 词法环境组件被创建

      • 环境记录:存储变量(let 和 const )和函数声明的实际位置

      • 对外部环境的引用: 用于访问其他外部词法环境

        词法环境有两种类型:

        1. 全局环境 :拥有一个全局对象(window对象)及其关联的所有属性和方法, 同时也包含了用户自定义的全局变量. 但是全局环境中没有外部环境的引用, 也就是外部环境引用为null.
        2. 函数环境: 用户在函数中自定义的变量和函数存储在环境记录中, 包含了arguments对象. 而对外部环境的引用可以是全局环境, 也可以是另一个函数环境(比如一个函数中包含了另一个函数).
    • 变量环境组件被创建

      • 它具有上面定义的词法环境的所有属性.

    需要注意:词法 环境和 变量 环境的区别在于前者用于存储**函数声明和变量( letconst绑定,而后者仅用于存储变量( var )**绑定。

    这里就可以看出执行上下文 是由 词法环境变量环境 组成的

    var a;
    var b = 1;
    let c = 2;
    const d = 3;
    function fn (e, f) {
        var g = 4;
        return e + f + g;
    }
    a = fn(10, 20);
    //执行上下文
    GlobalExectionContext = { // 全局执行上下文
        ThisBinding: <Global Object>,
        LexicalEnvironment: {   // 词法环境
        	EnvironmentRecord: {   // 环境记录
            	Type: "Object",       // 全局环境
            	c: < uninitialized >,
                d: < uninitialized >,
            	fn: < func >
        	},
        	outer: <null>            // 外部环境引用
        },
        VariableEnvironment: {   // 变量环境
        	EnvironmentRecord: {   // 环境记录
        		Type: "Object",
        		a: < uninitialized >,
        		b: < uninitialized >
        	},
        	outer: <null>  
        }
    }
    FunctionExectionContext = { // 函数执行上下文
        ThisBinding: <Global Object>, // this绑定window, 因为调用fn的是window对象
        LexicalEnvironment: {   // 词法环境
        	EnvironmentRecord: {   // 环境记录
        		Type: "Object",       // 函数环境
        		Arguments: { 0: 10, 1: 20, length: 2 }
        	},
            outer: < GlobalLexicalEnvironment > // 全局环境的引用
        },
        VariableEnvironment: {   // 变量环境
        	EnvironmentRecord: {   // 环境记录
        		Type: "Object",
        		g: < uninitialized >
        	},
        	outer: < GlobalLexicalEnvironment > // 全局环境的引用
        }
    }
  2. 执行阶段

    • 变量赋值
    • 函数引用
    • 执行其他的代码
  3. 销毁阶段

    • 执行完毕出栈,等待回收被销毁

在ES5 环境下

执行上下文的分为三个阶段

  1. 创建阶段

    • 创建变量对象
      • 创建变量对象又会细分几个步骤具体参考分析阶段
    • 创建作用域链
    • 确定 this 指向
  2. 执行阶段

    • 变量赋值
    • 函数引用
    • 执行其他的代码
  3. 销毁阶段

分析阶段

当进入执行上下文时,这时候还没有执行代码,

变量对象会包括:

  1. 函数的所有形参 (如果是函数上下文)
    • 由名称和对应值组成的一个变量对象的属性被创建
    • 没有实参,属性值设为 undefined
  2. 函数声明
    • 由名称和对应值(函数对象(function-object))组成一个变量对象的属性被创建
    • 如果变量对象已经存在相同名称的属性,则完全替换这个属性
  3. 变量声明
    • 由名称和对应值(undefined)组成一个变量对象的属性被创建;
    • 如果变量名称跟已经声明的形式参数或函数相同,则变量声明不会干扰已经存在的这类属性

作用域链

决定 了各级上下文中的代码在访问变量和函数时的顺序。和执行上下文栈的概念相似。

参考

js执行上下文

JavaScript深入之词法作用域和动态作用域

[推荐看看](https://github.com/mqyqingfeng/Blog/issues/5)

JavsScript 变量提升和函数提升 - 写的非常不错

JS-变量提升和函数提升

@xiaochengzi6 xiaochengzi6 added the JavaScript JavaScript 语言的学习 label May 19, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
JavaScript JavaScript 语言的学习
Projects
None yet
Development

No branches or pull requests

1 participant