美文网首页
堆栈内存及栈结构

堆栈内存及栈结构

作者: 小生菜呢 | 来源:发表于2021-06-16 01:13 被阅读0次

    堆栈内存

    JS代码之所以能够在浏览器运行,是因为浏览器会从计算机的内存挑中分配出对应的内存,用来存储值和运行代码
    内存有两种:

    • Stack:栈内存 ECStack(Execution [ˌeksɪˈkjuːʃn] Context Stack),存储的值有两种:
      +原始值类型存储在栈内存中
      +提供对应的执行上下文 EC(Execution Context)供代码执行
    • Heap:堆内存
      +存储对象类型的值

    下边通过一段代码来具体了解一下:

    var a = {
        n: 1
    };
    var b = a;
    a.x = a = {
        n: 2
    };
    console.log(a.x);
    console.log(b);
    

    这段代码是如何运行的呢?

    image.png

    文字版

    1. 浏览器开辟堆内存和栈内存

    2. 堆内存中分配出一块空间(假设有个16进制地址0X000),存储内置的API:
      setInterval,setTimeout,JSON,requestAnimationFrame, open....等
      我们把这块空间叫做GO(global object):全局对象

    3. 为了区分是全局代码执行,还是函数代码执行,或者块级上下文执行,所以会进行区分
      这里是全局代码执行所以会形成EC(G):全局执行上下文(全局代码都会在这里执行)

    4. 形成全局上下文之后,代码进栈执行(执行完会出栈释放掉,不释放的话就会形成闭包)

    5. 在全局执行上下文中,会有一个空间叫VO(G):全局变量对象,存储全局上下文中声明的变量

      +特殊性:在新版本当中,在全局执行上下文中,【基于let/const声明的变量存放在这里,基于var/function声明的变量是直接存储到GO中的】

    6. 怎么访问GO中的东西呢?是因为浏览器会默认在全局执行上下文中声明一个变量叫:window,window指向GO的存储地址:0X000

    7. 代码执行(当然代码执行之前还要做好多事,比如说:词法分析,变量提升,作用域链等,以后再补充)

    • 代码执行过程中,遇到变量等于什么的时候都是:
      @1.先创建值
      @2.声明变量 declare
      @3. 变量和值关联 defined

    • 全局上下文中使用变量
      @1. 先看VO(G)中是否有
      @2 再看GO中是否有
      @3 如果都没有,则报错:变量为北定义

    • 如果是连等赋值:var a = b = 10,正常顺序都是从右到左:
      @1. 创建值10(存储再栈中)
      @2. b = 10
      @3. var a = 10
      但是遇到优先级较高的,则先执行优先级高的操作(例如一开头的代码中:a.x = a = {...}, .是成员访问,优先级高于=)

    • 执行:

    var a = {
        n: 1
    };
    var b = a;
    a.x = a = {
        n: 2
    };
    console.log(a.x);
    console.log(b);
    
    var a = {
        n: 1
    };
    

    @1: 堆内存中开辟一块空间:0X001
    存储:n:1
    @2: var 一个变量a,存储在GO中
    @3: a和0X0001关联
    a = {n:1}

    var b = a;
    

    @4: var b=a :将b指向a的内存地址:0X001
    b={n:1}

    a.x = a = {
        n: 2
    };
    

    @5: 堆内存再开辟一块空间:0X002
    存储:n:2
    @6: a.x 地址指向 0X002(.优先级高于=),所以a (地址:0X001)为

    {
      n:1,
      x: {
          n:2
      }
    }
    

    b和a指向的是同一个地址:0X001,所以b也是:

    {
      n:1,
      x: {
          n:2
      }
    }
    

    @7: a={n:2} a的地址指向0X002

    console.log(a.x); //  a={n:2} 并没有变量x,所以输出值是:undefined
    console.log(b); // console.log(b):b地址指向0X001,所以输出:{n:1,x:{n:2}}
    

    栈结构

    以后再补充

    相关文章

      网友评论

          本文标题:堆栈内存及栈结构

          本文链接:https://www.haomeiwen.com/subject/auvzeltx.html