JS基础之堆栈内存的区别

堆栈内存的区别

堆栈内存的区别(看图)

	let a = 12;
    let b = a;
    let c = {name: 'xiaoHua'};
    b = 13;
    console.log(a, c)
——————————————————————————————————————————————
    let a = {n:1};
    let b = a;
    a.x = a = { // 像这种连续等于要从左往右依次赋值
    n:2
    };    
    console.log(a.x, b);

JS基础之堆栈内存的区别_第1张图片
JS基础之堆栈内存的区别_第2张图片

堆内存和栈内存

打开一个页面,浏览器会形成两个虚拟的内存:堆内存、栈内存
栈内存存储了啥:变量、基本数据类型值、地址
堆内存存储了啥:存储了引用数据类型的值
PS:全局作用域、私有作用域都是栈内存,为代码执行提供必要的环境,理论上来说,存储的东西越少,运行的越快

堆栈内存销毁

  • 堆内存回收

    堆内存回收:GC垃圾回收机制;在浏览器内置了一个gC程序,这个程序会每隔一段时间执行一次;

    • 谷歌浏览器-标记法:浏览器每隔一段时间要对所有的空间地址类型进行检测,检查该地址是否被占用;如果没有占用,那么久立即回收掉
    • IE和火狐-计数法:浏览器采用计数的规则,如果空间地址被占用一次,那这个空间地址就默认+1,每空闲一次,空间地址就默认-1,如果浏览器发现有为0的空间地址,就把其回收
  • 堆内存销毁

		var obj = {};
        obj = null;
        // 谷歌浏览器:
  • 栈内存回收==>作用域销毁
  • 栈内存的销毁:立即销毁、不销毁 、不立即销毁
    • 作用域就是栈内存:全局作用域、私有作用域
      • 全局作用域的销毁: 一般情况情况不销毁,除非把当前页面关闭,整个作用域就销毁了
      • 私有作用域的销毁:立即销毁、不销毁 、不立即销毁
        • 不销毁:
          • (1)函数(包括自执行函数)要return一个引用数据类型值,(2),return要被外界接收
          • 如果当前作用域有个空间地址,被函数体外的东西占用着,那么这个栈内存就不能销毁;
          • 对象键值对的属性名对应的是个自执行函数并且返回值的是个函数,自执行函数作用域不销毁。
        • 不立即销毁:fn()()return一个小函数,马上让小函数执行,这时候外界的作用域不能立即销毁,他要等待小函数执行完成之后再销毁
        • 立即销毁:不能同时满足上边的两个条件,作用域就销毁了
          • 作用域销毁的例子
        /*         var i = 5;
        function fn(i) { // 1  2   3
            return function (n) { // 2         7  
                console.log(n + (++i)); // 4    10
            }
        }
        var f = fn(1);
        f(2);
        fn(3)(4);
        fn(5)(6);
        f(7);
        console.log(i); // 5

JS基础之堆栈内存的区别_第3张图片


        // function fn(){
        //     var name = 'jinYu',
        //     age = 18; 
        // }
        // fn();
        // fn();

        // (1)函数要return一个引用数据类型值;(2)return的值要被外界接收
        
        // function fn(){
        //     var name = 'jinYu',
        //     age= 16;
        //     return {
        //         name: name,
        //         age: age
        //     }
        // }
        // var res = fn()

    // 不销毁作用域
    // 1. 返回一个引用的数据类型值
    // 2. 返回的值需要被外界接受
    // var num =2;
    // function fn(){
    //     var num =1;
    //     return function(){
    //         console.log(num); // 1
    //     }
    //     return {}
    // }
    // var f = fn()
    // f();

    // 2. 如果当前作用域有个空间地址,被函数体外的东西占用着,那么这个栈内存就不能销毁;
    // function fn(){
    //     // oLis[i].onclick = function(){
    //     // }
    //     // var obj = {};
    //     // obj.a = function(){
            
    //     // }
    // }
    // fn()


    // 不销毁
    // var obj = {
    //     num:1,
    //     fn:(function(){
    //         // 不销毁
    //         return function(){

    //         }
    //     })()
    // }


    // 不立即销毁
        function fn(){
            var a = 12;
            return function(){
                console.log(a)
            }
        }
        fn()()
// 当外层大函数执行完成之后不能立即销毁,他要继续等待里面的小函数执行完成销毁之后,大函数在销毁

你可能感兴趣的:(JS)