「这是我参与2022首次更文挑战的第4天,活动详情查看:2022首次更文挑战」。
js设计模式
1、普通单例:
var stu1 = {
name: 'zhangsan',
age: 18,
sex: 'boy'
};
var stu2 = {
name: '李四',
age: 19,
sex: 'girl'
};
像上面这样,把描述一个事物的属性放到一个对象内这种封装方式称为单例模式。 单例模式的优点是解决了全局变量互相覆盖的问题。而 stu1 和 stu2 两个变量名又称为命名空间
2、 高级单例
高级单例:高级单例模式不再是直接将一个对象赋值给命名空间,而是先执行一个自执行函数,在函数执行结束时返回一个对象;
var 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
}
})();
这样写,有一个优势,我们可以在自执行函数的作用域中声明变量和函数,这个作用域不会销毁,我们可以在最后返回对象里面选择导出哪些变量和方法给外界使用,不导出的,外界拿不到;
单例模式虽然好用,但是有一个问题,有一个对象,我们就需要写一个这个对象,很繁琐。
3、工厂模式
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
工厂模式:像上面这样,把实现相同供的函数封装成一个函数,当我们需要创建一个实例的时候,我们就执行这个函数即可,并且每个对象都是单例; ==优势==:高内聚,低耦合 提高了代码的复用度
3.1什么是高内聚低耦合
高内聚就是说相关度比较高的部分尽可能的集中,不要分散
低耦合就是说两个相关的模块尽可以能把依赖的部分降低到最小,不要让两个系统产生强依赖
高内聚低耦合是软件设计的一个基本原则,说的是在程序的各个模块中,尽量让每个模块独立,相关的处理尽量在单个模块中完成,就是俗话说的:该干嘛干嘛去!优点:能提降低各模块的之间的联系,减少“牵一发而动全身”的几率,提高开发效率,降低升级维护成本,也便于进行单元测试,提高软件质量。
构造函数
构造函数模式:
通过 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 是一个类,这里类型抽象了老师的属性,一个老师有的属性有姓名,年龄,教授学科,哪个学校的老师,以及老师会讲课的功能。
// 创建一个实例:
let mrMa = new Teacher('马宾', 18, 'js', '珠峰培训');
console.log(mrMa);
let mrJiang = new Teacher('姜文', 19, 'Architect-架构师', '珠峰培训');
console.log(mrJiang);
console.log(typeof mrJiang); // object
console.log(typeof mrMa); // object
// 通过浏览器控制台查看,这两个实例(对象)的前面出现了 Teacher,此时说明 mrMa 和 mrJiang 都属于 Teacher 类的实例。
发布订阅
发布订阅模式:
是模拟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);