likes
comments
collection
share

通过单例模式实现的性能优化

作者站长头像
站长
· 阅读数 21

单例模式的概念:

用最简洁的一句话来描述就是:单例模式是设计模式中最简单的形式之一。这一模式的目的是使得类的一个对象成为系统中的唯一实例。

这样做的好处是:有些实例,全局只需要一个就够了,使用单例模式就可以避免一个全局使用的类,频繁的创建与销毁,耗费系统资源。

同时,单例模式一般有以下特点:

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
评论
请登录