javascript 如何实现一个单例?

62 阅读1分钟

单例模式是一种创建型设计模式,它确保一个类只有一个实例,并提供了一个全局访问点来访问该实例。

单例的UML图表示如下:

截屏2023-08-02 15.57.49.png

从图中可以看出,通过getInstance可以获取SingleObject,以保证返回对象为全局唯一的。

javascript中实现单例方式,有以下几种:

全局变量法

利用闭包函数的特点,全局持有闭包函数,使得私有变量一直保留。每次访问的时候,都能返回原来创建的对象。这里使用自执行函数进行实现。先贴上具体实现代码。

let Singleton = (function () {
        let instance;

        function createInstance() {
          let object = new Object();
          return object;
        }

        return {
          getInstance: function () {
            if (!instance) {
              instance = createInstance();
            }
            return instance;
          }
        };
      })();
      
let instance1 = Singleton.getInstance();  
let instance2 = Singleton.getInstance();  
  
console.log(instance1 === instance2); // true
      

如上,通过自执行函数,获取了私有变量instance,每次调用getInstance的时候,都会返回原来的对象。

对象属性法

class Singleton {  
    constructor() {  
        if (Singleton.instance) {  
            return Singleton.instance;  
        }  
        Singleton.instance = this;  
    }  
}  
  
let instance1 = new Singleton();  
let instance2 = new Singleton();  
  
console.log(instance1 === instance2); // true

看对象属性法之前,先看下什么是class

class Point {
  constructor(x, y) {
    this.x = x;
    this.y = y;
  }

  toString() {
    return '(' + this.x + ', ' + this.y + ')';
  }
}

传统方法实现方式如下:

function Point(x, y) {
  this.x = x;
  this.y = y;
}

Point.prototype.toString = function () {
  return '(' + this.x + ', ' + this.y + ')';
};

var p = new Point(1, 2);

因此,在设置 Point.instance 时候,相当于给PointFunction添加了一个instance属性,并保存了最初的初始化对象。