1 . 享元模式
1.1定义
享元模式(FlyWeight): 通过共用大量细粒度的对象, 避免拥有相同内容造成额外的内存开销.主要用于减少对象的创建,以减少内存的占用和提高性能.
享元模式就是一种代码优化策略, 在浅显点解释就是: 相同部分提出来或采用其他形式优化点.
1.2 作用
1. 提供了一种方便的管理大量相似对象的简便方法
2. 减少对象的创建, 较低系统的内存,提高系统的性能
1.3 应用场景
- 场景一
最最最简单的享元模式01
提出相同的事件函数, 只需要定义一个函数就能够满足业务需求
const $ = selector => document.querySelector(selector);
$('.box1').onclick = function(){console.log(111)}
$('.box2').onclick = function(){console.log(111)}
$('.box3').onclick = function(){console.log(111)}
// 提出后
const clickEvent = function(){console.log(111);}
console.log($('.box3').onclick = clickEvent);// 返回 clickEvent 事件处理函数
$('.box1').onclick = $('.box2').onclick = $('.box3').onclick = clickEvent
最最最常见的享元模式 事件委托02
假设我们ul标签里面有很多个li标签, 我们需要给每个li标签身上添加一个点击事件
在不使用事件委托前, 我们可能写出如下代码
const clickEvent = function(){console.log(111);}
Array.from($('ul').children).forEach(li =>{
li.addEventListener('click' , clickEvent)
})
上面代码中我们通过遍历ul的所以li子节点元素并未其添加事件,因此每一个li元素身上的事件处理函数都是独立的, 在内存中会独立占用一块内存, 当li元素有1000个甚至1000个时,会大量的操作DOM, 造成明显的性能消耗
利用事件委托的写法
$('ul').addEventListener('click',ev =>{
if(ev.target.nodeName === 'LI'){
// code...
}
})
此时我们只给一个DOM元素身上添加了点击事件, 大大地减少了添加点击事件的次数也减少了对DOM的操作
- 场景二
// 假设现在要排出一周40节课的上课信息
// id=>老师的工号, name=>老师的名字, sex=>老师的姓名, time=>上课时间
// 定义课程信息类
class ClassInfo{
constructor(id,name,sex,time){
this.Tid = id;
this.Tname = name;
this.Tsex = sex;
this.time = time;
}
}
// 实例
let classListD = [
new ClassInfo("001", "小玉", "女", "周一 7:20"),
new ClassInfo("002", "小莲", "女", "周二 7:20"),
new ClassInfo("003", "小白", "男", "周三 7:20"),
new ClassInfo("004", "小黑", "男", "周四 7:30"),
new ClassInfo("001", "小莲", "女", "周一 18:30"),
new ClassInfo("003", "小白", "男", "周一 19:30"),
new ClassInfo("002", "小玉", "女", "周一 20:30"),
//………………
];
// 很显然, 每一次实例我们都重新创建了老师的信息, 二这一部分的信息会有重复的
// 因为我们总共就4位老师,
// 这时候我们就可以使用享元模式来优化代码
// 定义基础的老师类 利用单例模式检测确保老师的信息只创建一次
let SingleTeacher = (function (){
//利用闭包保存老师的信息
let teacherIns = {}
return class{
constructor(id,name,sex) {
// 如果已经存在定义的老师信息, 就直接返回
if(teacherIns[id]) return teacherIns[id]
this.id = id;
this.name = name;
this.sex = sex
teacherIns[id] = this
}
}
})()
// 定义课程信息类
class ClassInfo{
constructor(id,name,sex,time){
this.thecher = new SingleTeacher(id,name,sex);
this.time = time;
}
}
总结:享元模式就是为了解决性能问题而生的模式, 把我们经常谈到的封装的概念说得更高一点.一般我们都配合单例模式实现.