JavaScript 设计模式之享元模式

享元

将一部分共用的方法提取出来作为公用的模块

javascript 复制代码
const Car = {
  getName: function () {
    return this.name
  },
  getPrice: function (price) {
    return price * 30
  }
}

const BMW = function (name, price) {
  this.name = name
  this.price = price
}
BMW.prototype = Car
const bmw = new BMW('BMW', 1000000)
console.log(bmw.getName()) // BMW
console.log(bmw.getPrice(1000000)) // 3000000

const Benz = function (name, price) {
  this.name = name
  this.price = price
}
Benz.prototype = Car
const benz = new Benz('Benz', 2000000)
console.log(benz.getName()) // Benz
console.log(benz.getPrice(2000000)) // 6000000

享元模式的应用目的是为了提高程序的执行效率与系统的性能。因此在大型系统开发中应用是比较广泛的,有时可以发生质的改变。它可以避免程序中的数据重复。有时系统内存在大量对象,会造成大量存占用,所以应用享元模式来减少内存消耗是很有必要的。

模板方法

假使我们有如下的样式

css 复制代码
.panel {
  width: 200px;
  min-height: 50px;
  box-shadow: 0 0 10px rgba(0, 0, 0, .5);
  padding: 10px;
  margin: auto
}

.btn-content {
  display: flex;
  justify-content: space-around;
}
.btn-content.right{
  flex-direction: row-reverse;
}

创建一个弹窗的基类

javascript 复制代码
const Alert = function (data) {
  if (!data) return
  this.content = data.content
  this.panel = document.createElement('div')
  this.contentNode = document.createElement('p')
  this.confirmBtn = document.createElement('span')
  this.closeBtn = document.createElement('b')
  this.footerBtn = document.createElement('div')
  this.footerBtn.className = 'btn-content'
  this.panel.className = 'panel'
  this.confirmBtn.className = 'btn-confirm'
  this.closeBtn.className = 'btn-close'
  this.confirmBtn.innerHTML = data.confirm || '确认'
  this.closeBtn.innerHTML = data.close || '关闭'
  this.contentNode.innerHTML = data.content || ''
  this.success = data.success || function () { }
  this.cancel = data.cancel || function () { }
}


Alert.prototype = {
  init: function () {
    this.panel.appendChild(this.contentNode)
    this.footerBtn.appendChild(this.confirmBtn)
    this.footerBtn.appendChild(this.closeBtn)
    this.panel.appendChild(this.footerBtn)
    document.body.appendChild(this.panel)
    this.bindEvent()
    this.show()
  },
  bindEvent: function () {
    this.confirmBtn.onclick = () => {
      this.success()
      this.hide()
    }
    this.closeBtn.onclick = () => {
      this.cancel()
      this.hide()
    }
  },
  show: function () {
    this.panel.style.display = 'block'
  },
  hide: function () {
    this.panel.style.display = 'none'
  }
}

基类主要用来实现一些常规的样式布局

定义一个标准的提示框

javascript 复制代码
const TitleAlert = function (data) {
  Alert.call(this, data)
  this.title = data.title
  this.titleDom = document.createElement('h3')
  this.titleDom.style.textAlign = 'center'
  this.titleDom.innerHTML = this.title
  this.panel.className += ' title-panel'
}
TitleAlert.prototype = new Alert
TitleAlert.prototype.init = function () {
  this.panel.insertBefore(this.titleDom, this.panel.firstChild)
  Alert.prototype.init.call(this)
}

确认按钮位置在左/右

javascript 复制代码
const LeftAlert = function (data) {
  TitleAlert.call(this, data)
  this.panel.className += ' left-panel'
  this.footerBtn.className += ' left'
}
LeftAlert.prototype = new Alert
LeftAlert.prototype.init = function () {
  TitleAlert.prototype.init.call(this)
}

const RightAlert = function (data) {
  TitleAlert.call(this, data)
  this.panel.className += ' right-panel'
  this.footerBtn.className += ' right'
}
RightAlert.prototype = new Alert
RightAlert.prototype.init = function () {
  TitleAlert.prototype.init.call(this)
}

使用

javascript 复制代码
new LeftAlert({
  title: '提示',
  content: '这是一个自定义的右上角弹窗',
  btnText: '确定',
  success: function () {
    console.log('点击了确定按钮');
  },
  cancel: function () {
    console.log('点击了取消按钮');
  }
}).init();

效果

模板方法的核心在于对方法的重用,它将核心方法封装在基类中,让子类继承基类的方法,实现基类方法的共享,达到方法共用。

相关推荐
ashcn20012 分钟前
水滴按钮解析
前端·javascript·css
爱吃奶酪的松鼠丶9 分钟前
React长列表,性能优化。关于循环遍历的时候,key是用对象数据中的ID还是用索引
javascript·react.js·性能优化
xkxnq33 分钟前
第二阶段:Vue 组件化开发(第 17天)
javascript·vue.js·ecmascript
豆苗学前端38 分钟前
你所不知道的前端知识,html篇(更新中)
前端·javascript·面试
sophie旭1 小时前
内存泄露排查之我的微感受
前端·javascript·性能优化
会员果汁1 小时前
15.设计模式-组合模式
设计模式·组合模式
Hilaku2 小时前
我用 Gemini 3 Pro 手搓了一个并发邮件群发神器(附源码)
前端·javascript·github
全栈前端老曹2 小时前
【包管理】npm init 项目名后底层发生了什么的完整逻辑
前端·javascript·npm·node.js·json·包管理·底层原理
YUEchn2 小时前
无处不在的Agent
设计模式·llm·agent