【吃透】JS设计模式 · 单例模式

单例模式

概念

单例模式是指在内存中只创建一次对象的设计模式。在程序中多次使用同一个对象且作用相同时,为了防止频繁地创建对象使得内存占用,单例模式可以让程序仅在内存中创建一个对象,让所有需要调用的地方都共享这一单例对象。

优点

适合于单一对象,只生成一个对象实例,避免频繁创建和销毁实例,减少栈内存占用。
只有一个实例且全局可访问该实例,便于维护一个全局实例对象

缺点

不适用动态扩展对象、创建多个相似对象的场景

代码实现

let A = function (name) {
    this.name = name
    this.ins = null
}
A.getName = function (name) {
    return new A(name)
}
A.toNum = function (age) {
if(!isNaN(age)) {
    return Number(age)
} else {
    return '未知年龄'
}
}
// 实例控制器
A.insHandle = function (str) {
    if(this.ins) { //核心点 只允许有一个实例
        return this.ins
    }
    return this.ins = new A(str)
}

console.log(A.getName('张三').name, A.toNum(44), A.insHandle('这是一个实例').name) // 张三 44 这是一个实例

定义A函数, A为一个实例。因此我们可以在函数 A 中定义一个 insHandle() 方法来管控这个单例,
并创建返回类实例对象,而不是通过传统的 new 操作符来创建类实例对象。
this.ins 存储创建的实例对象,每次接收到创建实例对象时,判断 this.ins 是否有实例对象,有则返回,没有则创建并更新 this.ins 值,因此无论调用多少次 insHandle(),最终都只会返回同一个 A 类实例对象(return this.ins = new A(str))。

但是 这种管理单例的操作,与对象创建的操作,功能代码耦合在一起,不符合 “单一职责原则”,无法使用 new 来进行类实例化,需约束该类实例化的调用方式

我们就这一点 对他进行优化改进

let A = (function(){
    let ins;
    return function(name, age, msg) {
        if (ins) { //核心点 只允许有一个实例
            return ins;
        }
        this.name = name;
        this.age = age;
        this.msg = msg;
        return ins = this;
    }
})();

 A.prototype.getMsg = function() {
    return `${ this.name } ${ this.age } ${ this.msg }`
 }
let zs = new A('张三', 44, '这是一个实例')
let ls = new A('李四', 32, '这是一个实例')
console.log(zs === ls); true
console.log(ls.getMsg());  // 张三 44 这是一个实例
console.log(zs.getMsg());  // 张三 44 这是一个实例

你可能感兴趣的:(【吃透】JS设计模式 · 单例模式)