JavaScript变量存储机制

本文探讨JavaScript中变量的存储机制,包括堆与栈的区别、局部/全局/闭包变量的存储,以及不同类型变量(如String、Number、OddBall等)如何存储。结论指出,所有变量都在堆中,栈中存储引用地址,基础类型中小整数存储在栈中,其余在堆中。
摘要由CSDN通过智能技术生成

本文分两个部分讨论变量存储模式

  • 局部/ 全局/ 闭包变量的存储机制: 在这部分我们讨论什么样的变量有资格存储在栈中
  • 不同类型变量的存储机制: 在这部分我们讨论存储在栈中的元素究竟存的是字面量还是引用

先说结论: 万物都存在堆中, 有的变量会在栈上存储引用地址

堆与栈

  • 堆是一个很大的内存存储空间, 你可以在里面存储任何类型数据. 操作系统不会自动回收. 在栈中存储不了的数据比如对象就会被存储在堆中, 在栈中呢是保留了对象在堆中的地址, 也就是对象的引用.
  • 栈是内存中一块用于存储局部变量和函数参数的线性结构, 遵循着先进后出的原则. 数据只能顺序的入栈, 顺序的出栈. 内存中栈区的数据, 在函数调用结束后, 就会自动的出栈, 不需要程序进行操作, 操作系统会自动回收

于是出现了一个问题, 在闭包出现时, 函数是如何访问到闭包所在的已经销毁的栈中的变量的呢?

局部/全局/闭包变量的存储机制

  • 局部变量: 最简单的, 局部变量存储在作用域所在的栈空间中, 例如

    function demo() {
         
      let a = 1;
      let b = '213';
      let c = [213];
      let d = new Object();
    }
    
    console.dir(demo);
    
    // ƒ demo()
    //   arguments: null
    //   caller: null
    //   length: 0
    //   name: "demo"
    //   prototype:
    //     constructor: ƒ demo()
    //     [[Prototype]]: Object
    //   [[FunctionLocation]]: demo.html:53
    //   [[Prototype]]: ƒ ()
    //   [[Scopes]]: Scopes[1]
    //     0: Global {0: Window, window: Window, self: Window, document: document,
    

    在上面我们找不到定义的变量, 在DevTools的内存-堆分析中也找不到他们

  • 全局变量

    • 使用var声明的全局变量
      使用var声明全局变量其实仅仅是为global对象添加了一条属性, 全局变量会被默认添加到函数作用域链的最底端, 也就是[[Scopes]]中的最后一个

      var aaa = 1;          // 随便var一个变量
      // 等同于 window.aaa = 1;
      console.dir(()=>{
             })   // 随便打印一个函数看看他的作用域
      
      // anonymous()
      //   length: 0
      //   name: ""
      //   arguments: (…)
      //   caller: (…)
      //   [[FunctionLocation]]: VM167:1
      //   [[Prototype]]: ƒ ()
      //   [[Scopes]]: Scopes[1]    <- 看到函数的作用域
      //     0: Global              <- 只有global(window)作用域
      //       aaa: 1               <- 看到window上的aaa
      //       alert: ƒ alert()
      //       atob: ƒ atob()
      //       blur: ƒ blur()
      //       btoa: ƒ btoa()
      
    • 使用let/const声明全局变量不会修改window对象, 而是将变量的声明放在了一个特殊的对象Script

      let t1 = 1;
      const t2 = 2;
      console.dir(()=>{
             })
      
      // anonymous()
      //   length: 0
      //   name: ""
      //   arguments: (…)
      //   caller: (…)
      //   [[FunctionLocation]]: VM99:1
      //   [[Prototype]]: ƒ ()
      //   [[Scopes]]: Scopes[2]      <- 查看作用域
      //     0: Script {t1: 1, t2: 2}   <- 看到这些数据被存储到了Script对象中
      //     1: Global {window: Window, self: Window, document: document,...}
      
  • 闭包中的变量: 闭包中的变量会在子函数调用的时候存储为一个对象(存储在堆中), 并在[[Scopes]]Closure(闭包)中体现

    function testCatch1 () {
         
      let a1 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Liukairui

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值