代理模式
为其他对象提供一种代理以控制这个对象
class Star {
play() {
console.log('show');
}
}
class StarProxy {
constructor() {
this.superStar = new Star()
}
talk(price) {
if (price > 10000000) {
this.superStar.play()
} else {
console.log('No!!');
}
}
}
let jjr = new StarProxy()
jjr.talk(20000000)
proxy代理
let worker = {
name:'张三',
workprice: 10000
}
let proxy = new Proxy(worker, {
get(target, key) {
if (key === 'workprice') {
console.log('读价格属性');
}
return target[key]
},
set(target, key, value) {
if (key === 'workprice') {
console.log('设置工钱属性');
if (value > 10000) {
console.log('工作');
} else {
console.log('罢工');
}
}
}
})
proxy.workprice = 6000
观察者模式
包含观察目标和观察者,一旦观察目标的状态改变,所有观察者都会收到通知,一个观察目标可以有任意多个观察者。
class Subject {
constructor() {
this.observers = [];
}
add(observer) {
this.observers.push(observer)
}
remove(observer) {
this.observers = this.observers.filter(item=>item!==observer)
}
notify() {
this.observers.forEach(item => {
item.update()
})
}
}
class Observer {
constructor(name) {
this.name = name
}
update() {
console.log('快快快更新', this.name);
}
}
let subject = new Subject()
let ob1 = new Observer('张三')
let ob2 = new Observer('李四')
subject.add(ob1)
subject.add(ob2)
subject.notify()
发布订阅者模式
发布者和订阅者互相不用知道,通过第三方实现调度,属于解耦合的观察者模式。
let pubSub = {
message:{},
publish(type, data) {
if (!this.message[type]) {
return
}
this.message[type].forEach(item => item(data));
},
subscribe(type, callBack) {
if (!this.message[type]) {
this.message[type] = [callBack]
} else {
this.message[type].push(callBack)
}
},
unsubscribe(type, callBack) {
if (!this.message[type]) {
return
}
if (!callBack) {
//取消所有当前的Type事件
this.message[type] && (this.message[type].length = 0)
} else {
this.message[type] = this.message[type].filter(item => item!==callBack)
}
}
}
function testA(data) {
console.log('testA',data);
}
function testB(data) {
console.log('testB',data);
}
function testC(data) {
console.log('testC',data);
}
pubSub.subscribe('a',testA)
pubSub.subscribe('a',testB)
pubSub.subscribe('b',testC)
模块模式
模块化模式最初被定义为在传统软件工程中为类提供私有和公共封装的一种方法。
能够使一个单独的对象拥有公共/私有的方法和变量,从而屏蔽全局作用域的特殊部分。这可以减少我们的函数名与在页面中其他脚本区域内定义的函数名冲突的可能性。
闭包写法
const obj = (function () {
//私有部分
let count = 0
//公有部分
return {
increase() {
return ++count
},
decrease() {
return --count
}
}
})()
console.log(obj);
es6写法
let count = 0
function increase() {
return ++count
}
function decrease() {
return --count
}
//暴露调用
export default {
increase,
decrease
}