一、闭包
闭包是指那些能够访问自由变量的函数,自由变量是指在函数中使用的,但既不是函数参数又不是函数的局部变量的变量,由此可以看出,闭包=函数+函数能够访问的自由变量,
二、有什么作用?
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的三个选项进行快照查看。
6、举例加内存泄漏解决方法
7、资料来源
四、用闭包写个单例模式
实现方法:
判断是否存在该对象的实例,如果已存在则不再创建
使用场景:
适用于业务场景中只能存在一个的实例,比如弹窗,购物车。
代码实现:
懒汉式: 在类加载时,不创建实例,因此类加载速度快,但运行时获取对象的速度慢;
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