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

 

posted @ 2020-06-21 01:14  半生难熟  阅读(257)  评论(0)    收藏  举报