内存释放(堆内存)和作用域(栈内存)销毁

  • 内存释放(堆内存)和作用域(栈内存)销毁
    • 对象数据类型或者函数数据类型在定义的时候会首先开辟一个堆内存

      // 堆内存的释放
      var obj1 = {name:'fff'}
      var obj2 = obj1;
      
      // {name:'fff'} 占用堆内存 该内存地址被引用次数为2
      
      // 想要释放内存/销毁, 只需要把引用他的变量值赋值为null即可, 即减少引用次数为0
      obj1 = null;
      obj2 = null;
      // 上面两次操作使堆内存的引用地址占用次数为0, JS引擎会在空闲的时候将内存销毁回收
      
    • 栈内存:全局作用域+函数作用域(私有)

      • 全局作用域: 只有当页面关闭的时候, 全局作用域才会销毁
      • 函数作用域:
        • 一般情况下, 函数执行的时候有一个新私有作用域, 当私有作用域中的代码执行完成后, 我们当前作用域会主动的进行释放和销毁
        • 特殊情况: 当前私有作用域中的部分内存被作用域以外的东西占用了, 那么当前这个作用域就不能被销毁了
          1. 函数执行返回了一个引用数据类型的值, 并且在函数的外面被一个其他变量给接收了, 这种情况下一把形成的私有作用域都不会被销毁

            function fn() {
                var num = 10;
                // 返回引用数据类型的值
                return function() {
                    num ++;
                    return num;
                }
            }
            // fn执行形成的私有作用域不会被销毁
            var f = fn();
            
            // 返回的是基本数据类型的值 会被销毁
            function fn() {
                var num = 10;
                return num
            }
            
          2. 事件绑定(函数执行的时候,私有作用域被函数以外的东西给占用的话, 当前作用域不会被销毁) -- 在一个私有的作用域中给DOM元素的事件绑定方法, 一般情况下我们的私有作用域都不会被销毁

            // 通过DOM方法获取的元素/元素集合都是对象数据类型的值
            var oDiv = document.getElementById(id)
            ~function() {
                oDiv.onClick = function clickFunc() {
            
                }
            }();// 当前自执行函数形成的这个私有作用域不会被销毁
            
            /*
                oDiv {
                    id,
                    className,
                    style:[object],
                    onClick: (由null变成指向clickFunc)
                }
            
                // 分析
                因为clickFunc的函数作用域被引用了, 不能够被销毁, 所以父级的作用域(立即执行函数作用域)也不能够被销毁
            */
            
          3. 连续执行-> fn返回的函数没有被其他的东西占用, 但是还需要执行一次, 所以暂时不销毁,当返回值执行完成后, 浏览器会在空闲的时候再进行销毁

            function fn() {
                var num = 12
                return function() {
                    console.log(num)
                }
            }
            
            fn(); // 执行调用会销毁栈内存, 因为返回值对象引用计数为0
            fn()() // 这种情况不会立即销毁,  用完一次之后在销毁
            

你可能感兴趣的:(内存释放(堆内存)和作用域(栈内存)销毁)