javascript观察者模式
观察者模式:当一个对象的状态发生改变,所有依赖于它的对象都将得到通知
通用发布订阅
var event = {
clientList:[],
listen: function (key, fn) {
if(!this.clientList[key]){
this.clientList[key] = [];
}
this.clientList[key].push(fn);
},
trigger: function () {
var key = Array.prototype.shift.call(arguments); //第一个参数是订阅的方法,后面为调用函数时的参数
fns = this.clientList[key];
if(!fns || fns.length === 0){ //没有绑定的订阅函数
return false;
}
for (var i = 0, fn; fn = fns[i++];){ //传递的绑定方法可能是多个的以数组传递的
fn.apply(this, arguments);
}
}
};
var installEvent = function (obj) { //给对象上绑定订阅模式
for (var i in event){
console.log(i);
obj[i] = event[ i ];
}
};
var salesOffices = {};
installEvent(salesOffices); //安装订阅模式
salesOffices.listen('squareMeter88', function (price) {
console.log('价格='+price);
});
salesOffices.listen('squareMeter100', function (price) {
console.log('价格='+price);
});
salesOffices.trigger('squareMeter88', 2000000);
salesOffices.trigger('squareMeter100', 3000000);
使用一个中间对象
使用中间对象,使事件触发和事件监听剥离
var Event = (function () {
var clientList = {},
listen,
trigger,
remove;
listen = function (key, fn) {
if(!clientList[key]){
clientList[key] = [];
}
clientList[key].push(fn);
};
trigger = function () {
var key = Array.prototype.shift.call(arguments);
fns = clientList[key];
if(!fns || fns.length === 0){
return false;
}
for(var i = 0, fn; fn=fns[i++];){
fn.apply(this, arguments);
}
};
remove = function (key, fn) {
var fns = clientList[key];
if(!fns){
return false;
}
if(!fn){ //表明要清空
fns && (fns.length = 0)
} else {
for(var l = fns.length-1; l >= 0; l--){
var _fn = fns[l];
if(_fn === fn){
fns.split(l, 1);
}
}
}
};
return{
listen: listen,
trigger: trigger,
remove: remove
}
})();
Event.listen('squareMeter88', function (price) {
console.log('价格=' + price);
});
Event.trigger('squareMeter88', 2000000);
使用,模块间通信
<body>
<button id="count">点击</button>
<div id="show"></div>
</body>
<script>
var a = (function () {
var count = 0;
var button = document.getElementById('count');
button.onclick = function () {
Event.trigger('add', count++);
}
})();
var b = (function () {
var div = document.getElementById('show');
Event.listen('add', function (count) {
div.innerHTML = count;
})
})();
</script>
按钮点击后将在div中显示点击的次数