1 单例模式
1.1普通的单例模式
var stu1 = {
name: 'zhangsan',
age: 18,
sex: 'boy'
};
var stu2 = {
name: '李四',
age: 19,
sex: 'girl'
};Ï
像上面这样,把描述事物的属性放到一个对象内这种封装方式称为单例模式。单利模式的优点就是解决啦全局变量相互影响相互覆盖的问题,而stu1 和 stu2 又可以称为命名空间
哈哈没有想到吧
1.2 高级单例模式
高级单例:高级单例故名思义就不会再像上面一样啦,不再是直接将一个对象赋值给命名空间,而是先执行一个自执行函数,在函数执行结束时返回一个对象
const person = (function () {
function eat(food) {
console.log(`I like eating ${food}`)
}
function hobby(h) {
console.log(`I like playing ${h}`)
}
var account = '$10000000';
var name = '王老五';
var age = 40;
return {
name: name,
age: age,
eat: eat,
hobby: hobby
}
})();
2 工厂模式
function reg(name, age, sex) {
var obj = {}; // 原材料
obj.name = name; // 加工
obj.age = age; // 加工
obj.sex = sex; // 加工
return obj; // 出厂
}
let s1 = reg('阿三', 19, 'boy');
let s2 = reg('李四', 18, 'girl');
console.log(s1 === s2); // false
工厂模式:像上面这样,把实现相同的函数封装成一个函数,当我们需要创建一个实例的时候,我们就执行这个函数即可,并且每个对象都是单例, 优势:高内聚,低耦合,提高代码的复用程度。
2.1 什么是高内聚 低耦合
高内聚: 就是相似度比较高的部分尽可能的集中在一起,不要分散,
低耦合: 就是两个相关的模块尽可能把依赖的部分降到最低,不要让两个系统产生强依赖。
高内聚低耦合是软件设计的基本原则,说的是程序的各个模块中,尽量让每个模块独立,相关的处理尽量在单个模块中完成,就是俗话说: 该干嘛干嘛去。
优点: 能降低各个模块之间的联系 减少牵一发而动全身 的概率 提高开发效率 降低维护成本 也便于单元测试 提高软件质量,
一般在中大项目做代码优化会用到这个原理
3 构造函数
构造函数模式: 通过 new 调用一个函数,此时这个函数不再是普通的函数 而是成为以恶搞类,函数名成为类名,而通过new调用,自动返回这个类的一个实例,在构造函数中,我们需要抽象这个类的属性和功能
function Teacher(name, age, subject, from) {
this.name = name;
this.mission = '处理问题';
this.age = age;
this.subject = subject;
this.from = from;
this.teach = function () {
console.log(`${name} 解决 ${subject} 问题`);
}
} // Teacher 是一个类,这里类型抽象了老师的属性,一个老师有的属性有姓名,年龄,教授学科,哪个学校的老师,以及老师会讲课的功能。
// 创建一个实例:DD
let mrMa = new Teacher('张三', 18, 'js', 'DD');
console.log(mrMa);
console.log(typeof mrMa); // object
// 通过浏览器控制台查看,这两个实例(对象)的前面出现了 Teacher,此时说明 mrMa 和 mrJiang 都属于 Teacher 类的实例。
4 发布订阅
发布订阅模式: 是模拟DOM2级事件池思想,在某一刻到来的时候,我们要做很多事(很多函数执行)。我们准备一个数组当做事件池, 并且提供向事件池中加入函数的方法以及移除的方法,当时刻来临时,我们把使劲啊池中的方法取出挨个执行。
订阅:订阅该时刻到来,把想做的事情加入事件池,
发布:时刻真的到来了,把事件池中的方法都执行了
// 准备事件池:
let ary = [];
function addListener(fn) {
if (ary.includes(fn)) return;
ary.push(fn)
}
function removeListener(fn) {
// 数组.filter 方法,把数组中满足条件的(回调函数返回true的项)组成一个新数组,原数组不变;
ary = ary.filter(item => item !== fn);
}
function fire() {
ary.forEach(item => item())
}
function fn1(_this) {
console.log(1)
}
function fn2() {
console.log(3)
}
function fn3() {
console.log(3)
}
// 订阅5s后的这个时刻
addListener(fn1);
addListener(fn2);
addListener(fn3);
// 取消订阅
removeListener(fn3);
setTimeout(function () {
// 5s后时刻来临,就把事件池中的方法都执行了
fire(this);
}, 5000);