小序:
经过前几天的面试,发现自己一直停留在应用层,对底层的一些原理总是云里雾里,也没有笼统的去透一遍,发现一本掘金小册炒鸡nice推荐哦~这个下篇再分享心得,这篇我们来说观察者模式
观察者模式
观察者模式是定义对象间一种一对多的依赖关系,当一个对象发生改变时,通知所有依赖于它的对象,举个例子在你使用原生js为dom绑定事件时,你就已经使用了观察者模式,无意间就能用到。
举个栗子:
当你加入一家大型公司,公司将你的照片及信息发布给所有的员工。
这就是一个很简单的例子
发布订阅模式的流程如下:
1. 确定谁是发布者(大型公司)。
2. 然后给发布者添加一个缓存列表,用于存放回调函数来通知订阅者。
3. 发布消息,发布者需要遍历这个缓存列表,依次触发里面存放的订阅者回调函数。
4. 退订(员工屏蔽新员工信息,就可以取消掉)
var obj = {}; // 发布者
obj.cacheList = []; // 缓存队列
obj.listen = function (key, fn) { // 添加新员工
if (!this.cacheList[key]) {
this.cacheList[key] = []
}
this.cacheList[key].push(fn)
}
obj.message = function () { // 发布消息
var key = Array.prototype.shift.call(arguments); //取出消息类型名称
var fns = this.list[key]; //取出消息对应回调函数集合
if(!fns || fns.length == 0){ //如果没有订阅这个消息,直接返回
console.log(key + "没有新员工入职");
return ;
}
for(var i = 0, fn; fn = fns[i++]; ){
fn.apply(this,arguments);
}
}
obj.listen("张三",function(age){ //订阅者
console.log("年龄 :" + age + '岁');
})
obj.message("张三", 25);
obj.message("李四", 30);
还有一种通过Object.defineProperty来实现
官方定义
Object.defineProperty:
方法会直接在一个对象上定义一个新属性,或者修改一个已经存在的属性, 并返回这个对象。
语法
Object.defineProperty(obj,prop,descriptor)
* obj: 需要定义属性的对象。
* prop: 需定义或修改的属性的名字。
* descriptor: 将被定义或修改的属性的描述符。
var obj = { // 创建对象
age: 1
}
function observer(oldVal, newVal) { // 定义值改变时的处理函数
console.log('name属性的值从 '+ oldVal +' 改变为 ' + newVal); // 其他处理逻辑...
}
Object.defineProperty(obj, 'name', { // 定义name属性及其set和get方法
configurable: true, // 属性是否可以被修改或者删除,默认 false
enumerable: true, // 属性是否可枚举,默认 false。
get: function() { // 获取属性的方法。
return name;
},
set: function(val) { // 设置属性的方法。
observer(name, val) // 调用处理函数
name = val;
}
});
obj.name = 'Martin';
obj.name = 'Lucas';
console.log('obj:', obj)