/***
*
* 建立多個事件池
* + 每個事件池是獨立的,存放自己訂閱的方法
* + 但是也可以具備共同的方法 on/off/fire
* => 面向對象中的類和執行個體
*/
(function(){
class Sub{
// 執行個體私有屬性
pond = [];
// 原型公共方法
on(func){
let pond = this.pond;
!pond.includes(func) ? pond.push(func) : null;
}
off(func){
let pond = this.pond;
pond.forEach((item,index)=>{
if(item === func){
pond[index] = null;
}
})
}
fire(...params){
let pond = this.pond;
for(let i=0;i<pond.length;i++){
let itemFunc = pond[i];
if(typeof itemFunc !== "function"){
// 移除 null
pond.splice(i,1);
i--;
continue;
}
itemFunc(...params);
}
}
window.subscribe = function sub(){
return new Sub;
})();
//====
// 測試
const fn1 = (x,y)=>{
console.log('fn1',x,y);
}
const fn2 = ()=>{
console.log('fn2');
sub1.off(fn1);
sub1.off(fn2);
const fn3 = ()=>{
console.log('fn3');
const fn4 = ()=>{
console.log('fn4');
const fn5 = (x,y)=>{
console.log('fn5',x,y);
let sub1 = subscribe(),
sub2 = subscribe();
sub1.on(fn1)
sub1.on(fn2)
sub1.on(fn3)
sub1.on(fn4)
sub1.on(fn5)
sub2.on(fn1)
sub2.on(fn3)
document.body.onclick = function () {
// 通知事件池的方法執行
sub1.fire(10,20);
sub2.fire(100,200);
}