单例模式:顾名思义也就是单个实例模式,可以保证一个类只能生成一个实例,并且提供一个访问它的全局访问点,我们需要限制函数实例化得行为,可以使用闭包类来实现单例模式。
单例模式的优点:可以用来划分命名空间,减少全局变量的数量,多次实例化也是同一个实例。
单例模式应用场景:线程池、全局缓存、window对象、登录浮窗等。
在实现单例模式前,先说说闭包类,就是在闭包类添加一个内部类,外部访问不到这个内部类。
(function () {
function People(){ //闭包类
}
})()
单例模式可以分为:普通单例和惰性单例。
1、普通单例
普通单例:指的是在定义的时候,就会进行初始化的单例模式。普通单例被初始化的时机是“页面加载时”,本来页面就需要加载很多内容,若单例内如果也有内容,那么页面加载时所加载的内容就会增多,用户看到页面时间就会变长。
let instance = (function () {
function People(name, age, sex){//定义闭包类
this.name = name
this.age = age
this.sex = sex
}
let instance = new People('小', 18, '男')
//返回接口函数
return function(){//因为实例已经被初始化了,则不需要判断了
return instance
}
})()
2、惰性单例
惰性单例:初始化单例的时机是第一次调用单例模式的全局访问点时,也就是页面在加载时不需要提前加载单例所需内容。页面加载的内容相比于普通单例变少了,从而用户看到页面的时机就会稍微提前,优化了用户体验。
let instance = (function () {
function People(name, age, sex){//定义闭包类
this.name = name
this.age = age
this.sex = sex
}
//此时确实放入了闭包类,但是自己无法初始化。
//我们想要给外部提供一个接口,能让外部访问到内部的People类
let instance = null // 于是,定义一个变量,用于保存单例。闭包会一直将变量保存在内存中
//返回接口函数
return function(name, age, sex){//因为单例instance是否存在
if(!instance){//如果不存在,就初始化实例并返回
instance = new People(name, age, sex)
return instance
}
return instance//如果单例存在,也就是单例已被初始化过,那么返回该单例
}
})()
let a = instance('jin', 13, 'nan')
let b = instance('jin', 16, 'nan')
console.log(a === b); //true