休整了一阵子,身体和心理都慢慢恢复了一些。鸽了这么久终于补上这篇单例模式了,下面开始正题。
单例模式,顾名思义即一个类仅有一个实例。单例模式下即使多次调用构造函数(使用new操作符创建多个对象),得到的都是同一个实例对象。
使用静态属性的单例模式
使用构造函数本身的静态属性可以实现此功能,方法如下:
1 | function ClassA() { |
此方法的缺点在于静态属性instance可以在外部公开访问和修改,为解决此问题可以使用下面的方法。
使用闭包的单例模式
闭包方式
使用闭包进行封装可以确保instance变量的私有性,缺点是增加了额外的闭包开销。
1 | function ClassB() { |
原型链的继承关系
使用上面的闭包方式存在一个问题:由于构造函数被重写,在初始定义和重定义之间添加到类中的属性都会丢失。例如:
1 | function ClassC() { |
造成这种现象的原因是,重写构造函数后原先的构造函数因为使用了闭包还保留在内存中,但是构造函数指针已经指向了一个新的函数了。
与此同时ins1.constructor
仍然指向原始的构造函数而不是重定义之后的构造函数,因此ins1.constructor === ClassC
。原型链的继承关系可参见下面两个图:
classDiagram
Class --> ClassPrototype
ClassPrototype ..> Class
ClassPrototype <-- ins1: Prototype
ClassPrototype <-- ins2: Prototype
class Class{
prototype
}
class ClassPrototype{
constructor
}
class ins1{
prototype
}
class ins2{
prototype
}
原型链修复
对于上面提到的问题,我们需要对原型链进行修改。方法如下:
1 | function ClassC() { |
后记
简简单单把这篇的内容讲完了,虽然感觉还有很多细节没来得及说明,就这样吧。该填的坑总算填完了,以后再也不立flag了。设计模式剩下的几篇什么时候更新,随缘吧。
--- 本文结束 The End ---