通过单例模式实现的性能优化
单例模式的概念:
用最简洁的一句话来描述就是:单例模式是设计模式中最简单的形式之一。这一模式的目的是使得类的一个对象成为系统中的唯一实例。
这样做的好处是:有些实例,全局只需要一个就够了,使用单例模式就可以避免一个全局使用的类,频繁的创建与销毁,耗费系统资源。
同时,单例模式一般有以下特点:
1.构造方法私有化(即构造方法被private修饰)。
2 该单例对象必须由单例类自行创建。
3.内部提供一个公共静态的方法给外界进行访问(方法被public static 修饰)。
单例模式的实现:
所有初学者都会认同的一点就是,单例模式的实现实在是非常巧妙的,在这里,我先用最基本的方法来实现一个单例模式。
就比方说这段代码,如何在原有的基础上修改,使得输出的结果等于true
?
function Person() {
this.name = 'Tom'
}
let p1 = new Person()
let p2 = new Person()
console.log(p1 === p2) // 输出结果为false
答案是创建一个Person
类,再在其中添加一个名为getInstance()
的静态方法,这里使用静态方法的目的是使getInstance()
方法只能被类访问。
class Person {
constructor() {
this.name = 'Tom'
}
static getInstance() { // 静态方法使getInstance只能被类访问
if(!Person.instance){ //当Person已经被new过一次,证明类Person已经存在属性,于是直接返回
Person.instance = new Person()
}
return Person.instance
}
}
let p1 = Person.getInstance()
let p2 = Person.getInstance()
console.log(p1 === p2) //输出结果为true
可以看出,getInstance()
的作用就是当Person
已经被 new 过一次,证明类Person
已经存在属性,于是直接返回,防止产生新的对象,从而做到单例模式。
闭包实现完善的单例模式:
但要说更为完善高级一点的单例模式,那必须提一嘴闭包。同样是在上种方法的基础上改进,闭包又能玩出什么样的花样呢?
class Person {
constructor() {
this.name = 'Tom'
}
static getInstance() {
let instance = null
return function() {
if (!instance) {
instance = new Person()
}
return instance
}
}
}
const simple = Person.getInstance()
let p1 = simple()
let p2 = simple()
console.log(p1 === p2) //输出结果为true
别看这段代码只是在原有的基础上修改了寥寥几行,但背后执行的机理却是更为复杂许多。
有没有注意到在原有的基础上多出了一行:let instance = null
。
外部函数getInstance()
里面的内部函数function()
被返回到这个外部函数之外使用:正常流程getInstance()
函数的执行上下文执行完毕被销毁,但由于内部函数还在使用instance
这个变量,instance
在创建一次后的记录就被保留下来(不再为null),这就是单例模式中的闭包的执行机理。
于是,通过const simple = Person.getInstance()
; 获取Person
类的单例实例。
let p1 = simple
; 和 let p2 = simple
; 两次调用simple
都会得到相同的Person
实例。
最后
总之,众多单例模式核心思想为: 外部函数执行完一遍之后,内部函数再怎么调用,外部函数里面的变量都会被存在调用栈里边。
转载自:https://juejin.cn/post/7398087074971107343