// 由于这些成员对于任何发布者对象都是通用的,故将它们作为独立对象的一个部分来实现是很有意义的。那样我们可将其复制到任何对象中,并将任意给定对象变成一个发布者。
// 如下实现一个通用发布者,定义发布者对象……
class Publisher {
constructor(){
this.subscribers = {
any: []
}
}
subscribe(fn, type=`any`){
if(typeof this.subscribers[type] === `undefined`){
this.subscribers[type] = [];
}
this.subscribers[type].push(fn);
}
unSubscribe(fn, type=`any`){
let newArr = [];
this.subscribers[type].forEach((item, i) => {
if(item !== fn){
newArr.push(fn);
}
});
this.subscribers[type] = newArr;
}
publish(args, type=`any`){
this.subscribers[type].forEach((item, i) => {
item(args);
});
}
// 定义一个函数makePublisher(),它接受一个对象作为参数,通过把上述通用发布者的方法复制到该对象中,从而将其转换为一个发布者
static makePublisher(obj){
obj.publisher = new Publisher();
}
}
// 实现person对象
var person = {
sayHi: function(name){
this.publisher.publish(name);
},
sayAge: function(num){
this.publisher.publish(num, `age`);
}
}
// 将person构造成一个发布者
Publisher.makePublisher(person);
// 看看订阅对象myLover,该对象有两个方法:
var myLover = {
name: ``,
hello: function(name){
this.name = name;
console.log(`Hi, i am ` + name + ` ! Nice to meet you!`);
},
timeOfLife: function(num){
console.log(`Hello! My name is ` + this.name + ` ! I am ` + num + ` years old!`);
}
}
// person注册myLover(即myLover向person订阅)
person.publisher.subscribe(myLover.hello);
person.publisher.subscribe(myLover.timeOfLife, `age`);
// 即myLover为默认“any”事件提供了一个可被调用的方法,而另一个可被调用的方法则用于当“age”类型的事件发生时的情况。现在让我们来触发一些事件:
person.sayHi(`Jimmy`); // Hi, i am Jimmy ! Nice to meet you!
person.sayAge(24); // Hello! My name is Jimmy ! I am 24 years old!
person.sayHi(`Tom`); // Hi, i am Tom ! Nice to meet you!
person.sayAge(6); // Hello! My name is Tom ! I am 6 years old!
person.sayAge(18); // Hello! My name is Tom ! I am 18 years old!
console