JS

说说你对作用域链的理解

发布于 2021-01-11 17:14:04
关注者
0
被浏览
368
6 个回答
  • 面试哥
    面试哥 2021-01-12
    为面试而生,有面试问题,就找面试哥。

    JS中每个函数或者变量都有其自身的作用域,作用域可以理解为他们的执行环境。

    每次调用函数的时候都会对其生成一个作用域链,这个作用域链可用于在函数执行过程中查找执行涉及的变量和函数。

    查找顺序为当前执行函数内部->外部函数->>全局执行环境

    如下图例子就为son->test->全局

    let a = 1;
        var test = function () {
          let b = 2;
          var son = function () {
            let c = 3;
            console.log('a' + a, 'b' + b, 'c' + c)
          }()
        }()
    
  • 面试哥
    面试哥 2021-01-12
    为面试而生,有面试问题,就找面试哥。

    引擎初始化时首先会创建一个上下文环境作为初始全局执行上下文(global execution context), top level 的代码将在这个上下文中执行。 执行到函数调用时,引擎会创建新的执行上下文(每次调用都会产生新的执行上下文)。 执行上下文包含一张变量映射表(variable object)、this 指针、激活对象(全局执行上下文没有)和作用域链。 变量表记录着在该上下文执行环境下创建的局部变量和函数,函数调用生成的执行上下文额外包含由函数的参数构成的激活对象 (activation object),this 指针根据函数的调用方式不同而不同,而作用域链由当前作用域,即变量表和激活对象(函数参数),以及父作用域的引用构成。全局执行上下文是初始上下文,因此其作用域中没有父作用域引用,只包含变量表。而对于函数调用产生的执行上下文,函数在创建时(声明时),会记录下当时执行上下文中的作用域( chrome console 中以 [[scopes]] 形式展示),保存其引用,等到函数调用并创建执行上下文构造新的作用域时,便以此作用域作为父作用域。由一级级父作用域构成一个链式引用,此即称之为作用域链。链的顶端即全局作用域。

    在上下文中读取变量时,引擎会先在当前作用域中查找,即先查找激活对象,然后查找变量表,如果未找到,则通过作用域链中父作用域的引用,在父域中查找,依此类推,直到查找到全局上下文中的作用域。如果仍未找到则返回 undefined 。

    闭包:在某执行上下文中创建了一个函数,函数会引用当前上下文的作用域以备后续调用时创建新的执行上下文使用。一般地,在执行结束后(函数调用结束后),执行上下文会被销毁,其变量表,激活对象和作用域都将被销毁。但如果此次执行结束后,期间创建的函数仍在其他地方存在引用,则意味着该执行上下文中的作用域并不会被销毁,其变量表或激活对象中的变量引用也仍然存在。JS 引擎在处理函数声明对所处上下文作用域的引用时,并不会简单地引用整个作用域链,而会智能分析函数内部用到了当前作用域链上的哪些变量,然后创建一个作用域副本,并把这些变量放入其中。这一步称之为函数捕获了当前作用域中的某些变量,这些变量被关在了这个副本作用域中。直到这个函数的所有引用置空,函数被销毁,这个副本作用域才会被销毁,被捕获的变量才能得以释放。此即闭包。

    ES6 的块也会生成新的作用域,进入块时创建新的作用域并压入链顶,退出块时弹出作用域,但不产生新的执行上下文。

  • 面试哥
    面试哥 2021-01-12
    为面试而生,有面试问题,就找面试哥。

    1 如果是函数环境,arguments 对象
    2 下一个变量对象来自包含(外部)环境
    3 下一个变量对象,来自下一个包含环境
    4 ... 延续到全局执行环境(始终是最后一个对象)

  • 面试哥
    面试哥 2021-01-12
    为面试而生,有面试问题,就找面试哥。

    @haizhilin2013 是"作用域链"而不是“作用链域“

    作用域链与函数执行栈相对应。js运行环境分为全局、函数以及eval三类,每当代码执行进入了一个新的运行环境就会将环境的执行上下文入栈,退出环境时将其出栈,从栈顶到栈底形成从内层到外层的嵌套关系。

    由执行上下文创建的词法环境持有外层执行上下文的词法环境引用,当JS引擎在当前词法环境中找不到相应的变量时,会逐层向外查找,如此形成的链表即为作用域链。

  • 面试哥
    面试哥 2021-01-12
    为面试而生,有面试问题,就找面试哥。

    作用域分为全局作用域和局部作用域,function会产生局部作用域,在全局环境中无法访问局部变量,局部环境内可以访问全局变量。若是函数中嵌套函数,嵌套的函数中还有函数,那么,这样就会形成作用域链。最内部的函数中的变量,会现在自身函数内找是否定义了改变量,若没定义,则向上一级函数中寻找,若上一级函数也没有定义,则继续向上寻找变量,直到全局环境,若还是没有找到,则报错。

  • 面试哥
    面试哥 2021-01-12
    为面试而生,有面试问题,就找面试哥。

    作用域链指的是代码执行时,
    查找变量的规则,
    先在当前自身的作用域查找,
    找不到在往上级作用域查找,
    查不到的话直至全局环境,
    当然全局环境不能访问局部作用域的变量

知识点
面圈网VIP题库

面圈网VIP题库全新上线,海量真题题库资源。 90大类考试,超10万份考试真题开放下载啦

去下载看看