闭包

108 阅读2分钟

一、闭包

闭包是指那些能够访问自由变量的函数,自由变量是指在函数中使用的,但既不是函数参数又不是函数的局部变量的变量,由此可以看出,闭包=函数+函数能够访问的自由变量,

二、有什么作用?

1、模仿块级作用域。2、保存外部函数的变量。3、封装私有变量。 4、缓存私有变量

三、存在的缺陷(内存泄漏)

1、内存泄漏

指的是变量A一直被全局引用,GC(垃圾回收机制)因为它被引用所以没法回收它,而且程序员丢失了对它的引用。

2、内存泄漏的特点

A、变量一直被全局代码引用,GC无法回收。

B、变量虽然被全局代码引用,但是程序员无法操作它。

3、JS里面造成内存泄漏的生活场景。

A、意外的全局变量

B、遗忘的定时器

C、不当的闭包

D、遗漏的dom元素

E、网络回调

4、查看内存泄漏的方法

使用google浏览器F12查看perfomance与memory,点击"Record"按钮,进行操作后点击stop。

1、查看HEAP的蓝色条情况,如果蓝色条一直上升,没有下降,说明存在内存泄漏。

2、另外,也可以使用 performance monitor 工具,在开发者工具里找到更多的按钮,在里面打开此功能面板,这是一个可以实时监控 cpu,内存等使用情况的工具,会比上面只能抓取一段时间内工具更直观一点:

5、定位出现内存泄漏的代码

方法一、看performance中蓝色条开始上升的起点,通过“main”找到JS代码,点击anonymous查看代码位置。

方法二、查看实时perfomance monitor

方法三、用memory的三个选项进行快照查看。

aaa.png

6、举例加内存泄漏解决方法

7、资料来源

www.cnblogs.com/dasusu/p/12…

四、用闭包写个单例模式

实现方法:

判断是否存在该对象的实例,如果已存在则不再创建

使用场景:

适用于业务场景中只能存在一个的实例,比如弹窗,购物车。

代码实现:

懒汉式: 在类加载时,不创建实例,因此类加载速度快,但运行时获取对象的速度慢;

    let single = (function(){
        let instance = null;

        // 初始化单例数值
        function init(){
            let obj = {
                good:[],
                buy(good){
                    this.good.push(good)
                }
            };
            return obj;
        }

        return {
            // 获取唯一对象
            getInstance(){
                if(instance == null)  {
                    instance = init();
                }
                return instance;
            }
        }
    }());

    let a = single.getInstance();
    a.buy(1);
    let b = single.getInstance();
    b.buy(2);
    console.log(b.good)     // [1,2]
    console.log(a === b)    // true

饿汉式: 在类加载时就创建了实例,所以类加载较慢,但获取对象的速度快。


    let single = (function(){
        let instance = init();   // 直接初始化

        // 初始化单例数值
        function init(){
            let obj = {
                good:[],
                buy(good){
                    this.good.push(good)
                }
            };
            return obj;
        }

        return {
            // 获取唯一对象
            getInstance(){
                return instance;
            }
        }
    }());

    let a = single.getInstance();
    a.buy(1);
    let b = single.getInstance();
    b.buy(2);
    console.log(b.good)     // [1,2]
    console.log(a === b)    // true