1. 工厂模式
用于生成各种实例的函数(最常见的,构造函数)
复杂工厂模式:
父类:是一个抽象类,不可以直接实例
子类执行自己的业务逻辑,实现自身的实例方法
function BicycleShop(name){
this.name = name;
this.method = function() {
return this.name;
}
}
BicycleShop.prototype = {
constructor: BicycleShop, // 为什么这里需要重新指定constructor属性呢?因为系统为BicycleShop分配的原型对象已经被你改变了,所以要重新指定。
sellBicycle: function() {
let bicycle = this.createBicycle();
bicycle.a();
bicycle.b();
return bicycle;
},
createBicycle: function() {
throw new Error('父类不能直接实例,需要子类来实例');
}
}
// 通过原型链继承
function extend(Sub, Sup) {
let F = function() {};
F.prototype = Sup.prototype;
Sub.prototype = new F();
Sub.prototype.constructor = Sub;
Sub.sup = Sup.prototype;
}
function BicycleChild(name) {
this.name = name;
BicycleShop.call(this, name);
}
extend(BicycleChild, BicycleShop);
BicycleChild.prototype.createBicycle = function(){
let a = function(){
console.log('执行a');
}
let b = function(){
console.log('执行b');
}
return {
a,
b
}
}
const bicycleChild = new BicycleChild();
2. 单例模式
划分命名空间,并将属性和方法组织在一起的一种方式;
只实例化一次,每次返回的实例都是同一对象。
function Singleton(name) {
this.name = name;
}
Singleton.prototype.getName = function() {
console.log(this.name);
}
let getInstance = (function(name){
let instance;
return function(name) {
if(!instance) {
instance = new Singleton(name);
}
return instance;
}
})();
// 绑定到静态属性
Singleton.getInstance = ....
let a = getInstance('张三');
let b = getInstance('李四');
// 都是张三
未完待续
3. 策略模式
将策略单独封装起来,比如 switch 替换成对象属性
4. 发布订阅模式–重要
定义对象一对多之间的依赖关系
典型:dom1.addEventListener(‘click’, function(){}) , eventBus
// 1. 主题 (售楼处)
// 2. 缓存列表
// 3. 当事件触发的时候(状态发生变化),依次执行回调函数
let salesOffices = {};
salesOffices.clientList = [];
salesOffices.listen = function(key, fn){
if(!this.clientList[key]){
this.clientList[key] = [];
}
this.clientList[key].push(fn);
}
salesOffices.trigger = function(){
const key = Array.prototype.shift.call(arguments),
fns = this.clientList[key];
for(let i = 0; i < fns.length; i++) {
fns[i].apply(this, arguments);
}
}
-----------------------------------------------------------------
const Event = {
clientList: [];
listen: function(key, fn){
if(!this.clientList[key]){
this.clientList[key] = [];
}
this.clientList[key].push(fn);
},
trigger(){
const key = Array.prototype.shift.call(arguments),
fns = this.clientList[key];
for(let i = 0; i < fns.length; i++) {
fns[i].apply(this, arguments);
}
}
}
function installEvent(target, Source) {
// for (let i in Source) {
// target[i] = Source[i];
// }
// return target
return Object.assign(target, Source);
}
let salesOffices = installEvent(salesOffices, Event);
-----------------------------
// 类
class Event {
constructor() {
this.clientList = {};
}
listen(key, fn){
if(!this.clientList[key]){
this.clientList[key] = [];
}
this.clientList[key].push(fn);
},
trigger(){
const key = Array.prototype.shift.call(arguments),
fns = this.clientList[key];
for(let i = 0; i < fns.length; i++) {
fns[i].apply(this, arguments);
}
// this.events[eventName] && this.events[eventName].forEach(fn => fn());
}
// 移除订阅事件
removeListener(eventName, callback) {
if (this.events[eventName]) {
this.events[eventName] = this.events[eventName].filter(cb => cb != callback)
}
}
// 只执行一次订阅的事件,然后移除
once(eventName,callback) {
// 绑定的时fn, 执行的时候会触发fn函数
let fn = () => {
callback(); // fn函数中调用原有的callback
this.removeListener(eventName,fn); // 删除fn, 再次执行的时候之后执行一次
}
this.on(eventName,fn)
}
}
class SalesOffices extends Event {
constructor() {
super();
}
}
let salesOffices = new SalesOffices();
--------------------------------
salesOffices.listen('square88', function(price, squareMeter){
console.log('价格:'+ price);
})
salesOffices.listen
salesOffices.listen
salesOffices.trigger('square88', 1000, 88);
5. 适配器模式
类比 电源适配器,笔记本充电器20v,家用220v
接口更新、数据格式更新
6. 装饰器模式
为对象添加新功能
不改变其原有的结构和功能
class Circle {
draw() {
console.log("画一个圆形");
}
}
class Decorator {
constructor(circle){
this.circle = circle;
}
draw() {
this.circle.draw();
this.setRedBorder(this.circle);
}
setRedBorder(circle) {
console.log("设置红色边框")
}
}
// 测试代码
let circle = new Circle();
circle.draw()
let dec = new Decorator(circle);
dec.setRedBorder();