JavaScript | 执行上下文到底是什么(面试篇)

1,130 阅读4分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第13天,点击查看活动详情

执行上下文

很多时候都说上下文调用,执行上下文,那么上下文到底是什么呢,我们具体分析一下。

从js引擎方面来看

  • JS引擎并非逐行解析,而是一段段的分析和执行。这个分析,就是执行一段代码之前的准备工作,这个准备工作被称作为'执行上下文',执行上下文其实也在内存中开辟了一块空间
  • JS可执行的代码段分为3种类型:1.全局 2.局部(函数) 3.eval()(不用)

从代码执行方面

为什么要有执行上下文

我们每运行一次代码,都会创建相对应的执行上下文,全局被称为全局执行上下文,局部被称为局部执行上下文。因为代码每次运行都会产生上下文的关联,所以需要有一个可以负责这些代码运行和管理的文件栈。

执行顺序

  • 代码最开始运行,首先执行的是全局执行上下文,所以会在栈中压入一个全局执行上下文,等待页面运行结束,才会弹出
  • 要执行一个函数,会创建一个局部执行上下文并压栈,当函数执行完成以后,就会把局部执行上下文从栈里弹出

从三个部分来具体剖析执行上下文

  • this
  • 变量对象
  • 作用域链

this

有讲过,可跳转链接查看 JavaScript | 预解析以及this调用

变量对象

当执行上下文开启的时候,变量对象就会被激活,激活以后,作用域才能使用变量

简单介绍变量对象

  • 变量对象和执行上下文相关,所以分为了 全局的变量对象(windown)和局部的变量对象
  • 进入局部执行上下文,首先要生成一个变量对象,保存当前局部作用域中所有的变量(形参、声明的变量、声明的函数)

变量对象的生成

  • 变量对象第一步先确定形参和实参,然后确定执行上下文中声明的函数,如果和形参同名,则完全覆盖
  • 确定执行上下文中声明的变量,如果变量和形参或函数同名,则变量在赋值之前不会干扰同名形参和函数,以后在执行上下文中,如果使用变量 则直接去变量对象中查找即可

简单用代码表示就是这样

 function fn(a) {
            //下边声明的a不影响形参a的值
            console.log(a); //1
            var a = 2;
            //变量a赋值之后,就覆盖之前的a
            console.log(a); //2
        }
        fn(1); 

作用域链

首先简单了解一下什么是作用域

作用域

什么是作用域

一句话概括:用来规定代码作用的范围及变量查询的范围

作用域的作用

隔离变量, 防止命名冲突

作用域什么时候产生及销毁

  • 代码定义的时候产生
  • 函数执行完销毁的是变量对象而不是作用域
  • 作用域从代码定义的时候就一直在,除非没有当前代码

作用域链

  • 函数创建的时候,会创建一个包含全局变量对象的作用域链(scope chain),作用域链是保证对执行环境有权访问的所有变量和函数 的有序访问
  • 函数执行的时候,会创建自身的变量对象,把当前变量对象插入到 声明函数时候生成的作用域链顶端,完成整个作用域链
  • 作用域链的顶端一定是当前执行环境的变量对象,作用域链末端一定是全局环境的变量对象window

作用域链的查找过程

查找变量的时候现在当前作用域的变量对象中查找,如果有就使用,如果没有会继续去上级作用域查找,直到找到全局作用域,如果还没有就报错,报错内容: xxx is not defined, 查找的过程就是沿着作用域链查找

结合作用域链面试题分析

 var scope = "1";

        function fn() {
            var scope = "2";

            function f() {
                return scope;
            }
            return f;
        }
        console.log(fn()());

分析

输出是2,万里不变其一,就是作用域链其实就是在函数声明和变量定义的时候就确定了的,不管在哪调用,只需要看在哪声明就行,函数内部调用沿着作用域链网上找,不难就得出结果为2。

总结(执行上下文环境)

js代码在正式执行之前js引擎会先做一些准备工作

  • 1.创建执行上下文环境
  • 2.创建一个空的对象(执行上下文对象),该对象用于收集当前作用域的:变量,函数,函数的参数
  • 3.确认this的指向
  • 4.创建当前环境的作用域链

好了,以上就是本篇文章的分享,感谢阅读!