【ES6】使用Proxy实现单例模式

前言

由于JS没有private关键字,无法私有化构造器,所以下面代码无法限制:

javascript 复制代码
class Person {
  constructor() {
    console.log("Person created");
  }
}

const p1 = new Person();
const p2 = new Person();

console.log(p1 === p2); // false

实现

通过 Person.getInstance() 生成对象

javascript 复制代码
class Person {
  constructor() {
    console.log("Person created");
  }
  static _ins = null
  static getInstance() {
    if (!this._ins) {
      this._ins = new Person();
    }
    return this._ins;
  }
}

const p1 = Person.getInstance();
const p2 = Person.getInstance();

console.log(p1 === p2);

但是如果创建对象时使用new Person(),仍无法实现单例模式。

下面封装一个函数,把任何类传入,将其变为单例模式:

javascript 复制代码
function singleton(className) {
  let ins
  return class {
    constructor(...args) {
      if (!ins) {
        ins = new className(...args)
      }
      return ins
    }
  }
}
class Person {
  constructor() {
    console.log("Person created");
  }
}

// const p1 = new Person();
// const p2 = new Person();
const SingletonPerson = singleton(Person);
const p1 = new SingletonPerson();
const p2 = new SingletonPerson();

console.log(p1 === p2);

但是这种实现方式仍有缺陷,并不能添加原型方法

javascript 复制代码
const SingletonPerson = singleton(Person);
const p1 = new SingletonPerson();
const p2 = new SingletonPerson();
SingletonPerson.prototype.say = function () {
  console.log("hello world");
}
p1.say();

下面使用 Proxy 实现,不返回一个新类,而是代理,给代理对象的原型上加方法等于直接给该对象的原型加方法。

javascript 复制代码
function singleton(className) {
  let ins
  return new Proxy(className, {
    construct(target, args) {
      if (!ins) {
        ins = new target(...args);
      }
      return ins
    }
  })
}
class Person {
  constructor() {
    console.log("Person created");
  }
}
const SingletonPerson = singleton(Person);
const p1 = new SingletonPerson();
const p2 = new SingletonPerson();
SingletonPerson.prototype.say = function () {
  console.log("hello world");
}
p1.say();
console.log(p1 === p2);
相关推荐
范特西是只猫1 小时前
echarts 自定义标注样式&自定义tooltip弹窗样式
前端·javascript·echarts
建群新人小猿1 小时前
CRMEB Pro版 DIY功能玩法即将升级,先来一睹为快!
前端·javascript·html
wrx繁星点点1 小时前
创建型模式-单例模式
java·开发语言·单例模式
WebGIS皮卡茂2 小时前
【数据可视化】Arcgis api 4.x 专题图制作之分级色彩,采用自然间断法(使用simple-statistics JS数学统计库生成自然间断点)
javascript·arcgis·信息可视化·前端框架
api773 小时前
1688商品详情API返回值中的售后保障与服务信息
java·服务器·前端·javascript·python·spring·pygame
赵广陆3 小时前
SprinBoot+Vue门诊管理系统的设计与实现
前端·javascript·vue.js·spring boot·maven
Python私教3 小时前
JavaScript 基于生成器的异步编程方案相关代码分享
android·javascript·okhttp
Bob99984 小时前
电脑浏览器访问华为路由器报错,无法访问路由器web界面:ERR_SSL_VERSION_OR_CIPHER_MISMATCH 最简单的解决办法!
开发语言·javascript·网络·python·网络协议·华为·ssl
B.-5 小时前
Remix 学习 - @remix-run/react 中主要的 hooks
前端·javascript·学习·react.js·web
2302_802836166 小时前
JS考核答案
javascript