作用域链与闭包

作用域链

核心原理

  1. VO中包含一个额外的属性(假设为 source),该属性指向创建该VO的函数本身
  2. 每个函数在创建时,会有一个隐藏属性[[scope]],它指向创建该函数时的AO
  3. 当访问一个变量时,会先查找自身VO中是否存在,如果不存在,则依次查找[[scope]]属性。

某些浏览器会优化作用域链,函数的[[scope]]中仅保留需要用到的数据。

示例分析

js 复制代码
<!doctype html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta http-equiv="X-UA-Compatible" content="ie=edge" />
    <title>Document</title>
  </head>

  <body>
    <script>
      var g = 0;

      function A() {
        var a = 1;

        function B() {
          var b = 2;
          var C = function () {
            var c = 3;
            console.log(c, b, a, g);
          };
          C();
        }

        B();
      }

      A();
    </script>
  </body>
</html>

说明:

蓝线:VO中包含一个额外的属性(假设为 source),该属性指向创建该VO的函数本身

红线:每个函数在创建时,会有一个隐藏属性[[scope]],它指向创建该函数时的AO

作用域链:当访问一个变量时,会先查找自身VO中是否存在,如果不存在,则依次查找[[scope]]属性(蓝红线交替 )

html 复制代码
<!doctype html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta http-equiv="X-UA-Compatible" content="ie=edge" />
    <title>Document</title>
  </head>

  <body>
    <script>
      var count = 100;
      
      function A() {
        var count = 0;
        return function () {
          count++;
          console.log(count);
        };
      }

      var test = A();

      test();
      test();
      test();

      console.log(count);
    </script>
  </body>
</html>

执行至 22 行时,执行上下文栈中的情况:

执行至 24 行时,执行上下文栈中的情况:

执行至 25 行时,执行上下文栈中的情况:

执行 count++时,线找寻 test 执行上下文中的 VO 是否有 count,如果没有,则根据 source寻找到创建该 VO 的函数本身,然后通过\[scope]属性寻找到下一个 VO,若有 count 则该 count++,否则再往下寻找。

闭包

重新理解闭包:

原理上理解:执行上下文已经销毁,但执行上下文中 VO 被保留下来,因为匿名函数中有一个\[scope]属性还指向他。并没有被垃圾回收器回收。

表面上理解:内部函数使用外部函数的变量,内部函数被外部调用。

相关推荐
OpenTiny社区37 分钟前
【直播分享】GenUI SDK 技术公开课第二讲 | GenuiChat 核心配置深度解析
前端·github
计算机魔术师38 分钟前
kernel.org 每天 600 万次请求,98% 不是人点的
前端
今日无bug1 小时前
从0到1手撕流式输出:Vue3 + Vite 实现 LLM 流式响应全解析
前端·vue.js·vite
光影少年1 小时前
react navite跨端项目的痛点、踩过哪些坑、怎么解决
前端·react native·react.js
默_笙1 小时前
🧀 用户访问一个网站到底经历了什么?全栈部署的"城市观光"指南
前端·javascript
aixingpan1 小时前
aixingpan.cn API开发文档:api_docs_trichart_natal_composite_transit2接口指南
前端·php
是立不是利1 小时前
CSS 架构——在混乱中建立秩序
前端·html
两只羊ovo1 小时前
让 Agent 接上“万能接口”:LangChain + MCP 实战,工具不再锁死在项目里
前端
妙码生花1 小时前
使用git更新ai-go-admin框架
前端·人工智能·git·golang·typescript·php
YUJIANYUE1 小时前
查立得万用查分电脑版(web环境+查询系统免安装单文件一键运行包)
前端·jvm