设计模式—单例模式(JS版本)

时间:2021-1-18 作者:admin

本文档已更新于 【前端橘子君】 【Github】

1、只能有一个实例
2、必须自己创造唯一实例

应用场景

  • 连接数据库,防止多次连接和断开
  • 购物车场景
  • 用户登录
  • vuex
  • 全局 loading 遮罩层
  • 生产唯一序列号
  • ……

ES6中的单例模式

// 购物车单例实例
class ShopCar {
  constructor () {
    // 保证只有一个实例
    if (!ShopCar.instance) {
      this.goodsList = [];
      ShopCar.instance = this;
    }
    return ShopCar.instance
  }
  addGood (good) {
    this.goodsList.push(good);
  }
  showGoodsList () {
    console.log(this.goodsList);
  }
}

var a = new ShopCar()
// 在分类页添加了一个商品
a.addGood({id: 1, name: '橘子'})
console.log(a.showGoodsList()) // 输出:[{id: 1, name: '橘子'}]

var b = new ShopCar()
// 在商品详情页添加了一个商品
b.addGood({id: 2, name: '苹果'})
console.log(b.showGoodsList()) // 输出:[{id: 1, name: '橘子'}, {id: 2, name: '苹果'}]

ES5中的单例模式

// ES5中的单例模式
var shopCar = (function () {
  var goodsList = [];
  var instance;
  return function () { // 调用了才会创建实例
    // 保证只有一个实例
    if (!instance) {
      // 实例
      instance = {
        addGood (good) {
          goodsList.push(good);
        },
        showGoodsList () {
          console.log(goodsList);
        }
      };
    }
    return instance;
  };
})();

var a = shopCar()
// 在分类页添加了一个商品
a.addGood({id: 1, name: '橘子'})
a.showGoodsList() // 输出:[{id: 1, name: '橘子'}]

var b = shopCar()
// 在商品详情页添加了一个商品
b.addGood({id: 2, name: '苹果'})
b.showGoodsList() // 输出:[{id: 1, name: '橘子'}, {id: 2, name: '苹果'}]

单例模式分为两种:懒汉式饿汉式

懒汉式

懒汉式:使用即创建,即加载时不会创建实例,只有加载时才会创建实例

上述代码就是一个懒汉式的单例模式,具体细节不再讲解。

shopCar是一个高级函数,其返回值是一个函数。

var shopCar = (function () {....})只是加载了一个shopCar而已,并没有调用,var a = shopCar()才是正式调用,此时才会进行if判断并创建实例。

饿汉式

饿汉式:加载即创建,即加载时就创建了实例,不用是否调用,都已经存在

将上述代码稍微改写一下

// ES5中的单例模式
var shopCar = (function () {
  var goodsList = [];
  var instance = { // 加载即创建实例
    addGood (good) {
      goodsList.push(good);
    },
    showGoodsList () {
      console.log(goodsList);
    }
  };
  // 调用的时候直接返回实例,保证只有一个实例
  return function () {
    return instance;
  };
})();

var a = shopCar()
// 在分类页添加了一个商品
a.addGood({id: 1, name: '橘子'})
a.showGoodsList() // 输出:[{id: 1, name: '橘子'}]

var b = shopCar()
// 在商品详情页添加了一个商品
b.addGood({id: 2, name: '苹果'})
b.showGoodsList() // 输出:[{id: 1, name: '橘子'}, {id: 2, name: '苹果'}]

优点

  • 确保了只有一个实例
  • 因为只有唯一实例,所以节省了系统资源,记住创建和销毁也需要浪费内存资源
  • 避免了对资源的多重占用,比如数据库的连接
  • 资源共享

更多相关文档,请见:

线上地址 【前端橘子君】

GitHub仓库【前端橘子君】

声明:本文内容由互联网用户自发贡献自行上传,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任。如果您发现有涉嫌版权的内容,欢迎进行举报,并提供相关证据,工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。