<script>
        function makeAdder() {
            var num = 5;
            return function() {
                return num++;
            }
        }
        var x = makeAdder(); //makeAdder创建作用域对象,makeAdder返回的函数引用该作用域对象(作用域对象不被销毁)
        console.log(x()); //5
        console.log(x()); //6
        x = null;    //返回函数的引用计数为0,释放makeAdder作用域对象
        var y = makeAdder();//makeAdder重新创建作用域对象,makeAdder返回的函数引用该作用域对象(作用域对象不被销毁)
        console.log(y()); //5
        console.log(y());  //6
    </script>
    

    image.png

    //当JavaScript执行一个函数时,都会创建一个作用域对象(scope object),用来保存在这个函数中创建的局部变量。他和被传入函数的变量一起被初始化。
    //注意点是:
    //第一,每次函数被执行的时候,就会创建一个新的,特定的作用域对象;
    //第二,与全局对象(在浏览器里面是当做window对象来访问的)不同的是,你不能从JavaScript代码中直接访问作用域对象,也没有可以遍历当前作用与对象里面属性的方法。
    //所以当调用 makeAdder 时,解释器创建了一个作用域对象,它带有一个属性:num。然后 makeAdder 返回一个新创建的函数。
    //通常 JavaScript 的垃圾回收器会在这时回收 makeAdder 创建的作用域对象,但是返回的函数却保留一个指向那个作用域对象的引用。结果是这个作用域对象不会被垃圾回收器回收,直到指向 makeAdder 返回的那个函数对象的引用计数为零。