单例模式又称单体模式,单例模式指的是一个构造函数一生只能有一个实例对象,无论对构造函数使用多少次new关键字,都只会有一个实例
单例模式的应用场景
单例设计模式的应用场景,比如应用自定义弹出层和登录框
非单例模式
// 声明一个构造函数 function Structure(){ this.num=1; } // 使用new关键字创建实例 let a=new Structure(); let b=new Structure(); // 对比俩个实例是否相等 console.log(a===b);
此时通过new关键字创建的俩个实例不相等,是因为通过new关键字创建出来的是一个对象,对象之间对比的是内存地址,a和b是俩个实例,内存地址不一样,所以不相等
这个在一般情况下是我们所期望的,但是在某些时候,我们期望他们共用一个实例
单例模式
我们在某些特殊场景,只希望共用一个实例,我们在创建实例时,先去看看该构造函数是否创建过实例,创建过实例的情况下,就读取缓存下来的实例对象并返回,如果没有创建就直接创建并缓存下这个对象,这里的重点就在第一次缓存下来的对象
//我们这里需要声明一个变量,用于实例创建第一次时候的缓存 let _unicode = null; // 创建函数 function Structure() { // 判断_unicode是否为null,为null就是第一次创建,需要赋初始值在返回,不为null就直接返回当前的_unicode if (_unicode == null) { // 初始值 _unicode = { num: 1 } } // 返回 return _unicode; } let a = Structure(); let b = Structure(); console.log(a===b);
这个时候a和b都已经相等了,因为创建构造函数的时候,都会去查看当前缓存的对象是否存在,存在即返回,不存在则创建完进行缓存,这样就会让他们使用的都是同一个内存地址
这里还存在一个问题,就是a创建完,在创建b之前对缓存对象进行修改,就会导致a和b是不同的存储位置,也会造成不相等的情况,这样不安全,我们现在要进行修改,我们这里可以通过闭包的方式把缓存对象变成私有属性,外部无法修改
let Structure = ( // 创建函数 function () { //缓存对象 let _unicode = null; // 返回一个函数行成闭包作用域 return function () { if (_unicode == null) { // 初始值 _unicode = { num: 1 } } return _unicode; } })(); let a = new Structure(); let b = new Structure(); console.log(a === b);
通过闭包的特性,实现了私有化属性,如果在a创建完,b创建之前去修改缓存对象,将会报错,因为缓存对象属于构造函数私有的,我们外部访问不到,这样就杜绝了能够在外部修改缓存对象,创建多个实例的问题,目前由于采用了闭包,缓存对象在私有化作用域中,所以无法通过外部修改,a和b存储数据的位置也不会发生更改,这样就实现了一个单例模式
坚持努力,无惧未来!