js设计模式之单例模式
什么是单例模式?
单例模式是指一个类永远只能返回一个实例。不论实例化了多少次这个类,返回的都是同一个类的内存引用地址。相当于后面实例化这个类时,仅仅是将第一次实例化的值引用,而非重新实例化一个新的对象。
单例的实现
每次在调用实例化这个类时,应该返回第一次实例化的对象,那么在第一次实例化时就应将实例化的对象保存或者缓存。由于多人协同开发中,可能会有多次实例化这个类,不能将这个实例化对象保存成为全局对象。所以可以将这个对象挂载到对象的某个属性上,在实例化时判断这个属性是否成功缓存了对象的引用地址,引用成功直接返回引用地址,引用失败则继续实例化新的对象。
构造方法实现
因为构造函数本身也是对象,可以拥有静态属性。所以可以这样实现:
function A(name){ // 如果已存在对应的实例 if(typeof A.instance === 'object'){ return A.instance } //否则正常创建实例 this.name = name // 缓存 A.instance =this return this } var a1 = new A() var a2= new A() console.log(a1 === a2)//true
这种方法的缺点在于静态属性是能够被人为重写的,不过不会像全局变量那样被无意修改。
借助闭包
通过闭包的方式来实现的核心思路是,当对象第一次被创建以后,重写构造函数,在重写后的构造函数里面访问私有变量。
function A(name){ var instance = this this.name = name //重写构造函数 A = function (){ return instance } // 第一种写法,这里实际上实现了一次原型链继承,如果不想这样实现,也可以直接指向原来的原型 A.prototype = this // 第二种写法,直接指向旧的原型 A.prototype = this.constructor.prototype instance = new A() // 调整构造函数指针,这里实际上实现了一次原型链继承,如果不想这样实现,也可以直接指向原来的原型 instance.constructor = A return instance } A.prototype.pro1 = "from protptype1" var a1 = new A() A.prototype.pro2 = "from protptype2" var a2= new A() console.log(a1.pro1)//from protptype1 console.log(a1.pro2)//from protptype2 console.log(a2.pro1)//from protptype1 console.log(a2.pro2)//from protptype2
var A; (function(name){ var instance; A = function(name){ if(instance){ return instance } //赋值给私有变量 instance = this //自身属性 this.name = name } }()); A.prototype.pro1 = "from protptype1" var a1 = new A('a1') A.prototype.pro2 = "from protptype2" var a2 = new A('a2') console.log(a1.name) console.log(a1.pro1)//from protptype1 console.log(a1.pro2)//from protptype2 console.log(a2.pro1)//from protptype1 console.log(a2.pro2)//from protptype2
利用在立即执行函数中保存一个私有变量instance,初次执行之后,第一次调用new A()之后,生成一个对象并让instance指向该对象,从第二次开始,调用new A(),都只返回这个对象
es6类实现
class SingletonApple { constructor(name, creator, products) { this.name = name; this.creator = creator; this.products = products; } //静态方法 static getInstance(name, creator, products) { if(!this.instance) { this.instance = new SingletonApple(name, creator, products); } return this.instance; } } let appleCompany = SingletonApple.getInstance('苹果公司', '乔布斯', ['iPhone', 'iMac', 'iPad', 'iPod']); let copyApple = SingletonApple.getInstance('苹果公司', '阿辉', ['iPhone', 'iMac', 'iPad', 'iPod']) console.log(appleCompany === copyApple); //true

浙公网安备 33010602011771号