简述
观察者模式指的是一个目标对象被多个观察者对象监听,当目标对象监听的属性发生变化时,主动向观察者发送通知。
实现
ES5
ES5 可以通过Object.defineProperty来设置set和get进行拦截来实现该模式。
代码
const observedObj = { _no: 1 }
const observerObj = { _no: 1 }
function observer(oldVal, newVal) {
console.log(`observed的no属性值变为${newVal}`)
observer._no = newVal
}
Object.defineProperty(observedObj, 'no', {
set(newVal) {
observer(this._no, newVal)
this._no = newVal
},
get() {
return this._no
}
})
observedObj.no = 2
console.log('observedObj: ', observedObj, '\nobserverObj: ', observerObj)const observedObj = { _no: 1 }
const observerObj = { _no: 1 }
function observer(oldVal, newVal) {
console.log(`observed的no属性值变为${newVal}`)
observer._no = newVal
}
Object.defineProperty(observedObj, 'no', {
set(newVal) {
observer(this._no, newVal)
this._no = newVal
},
get() {
return this._no
}
})
observedObj.no = 2
console.log('observedObj: ', observedObj, '\nobserverObj: ', observerObj)输出
observedObj的no属性值变为2
observedObj: { _no: 2 }
observerObj: { _no: 2 }observedObj的no属性值变为2
observedObj: { _no: 2 }
observerObj: { _no: 2 }ES6
使用 ES6 新特性 Proxy 和 Reflect 结合使用监听对象属性
代码
class Obj {
constructor(no) {
this.no = no
}
}
const observedObj = new Obj(1)
const observerObj = new Obj(1)
const handler = {
set(observed, key, value) {
if (key === 'no') {
observer(key, observed[key], value)
}
Reflect.set(observed, key, value)
}
}
const observerProxy = new Proxy(observedObj, handler)
function observer(key, oldVal, newVal) {
console.log(`observedObj的no属性值由${oldVal}变为${newVal}`)
observerObj[key] = newVal
}
observerProxy.no = 2
console.log('observedObj: ', observedObj, '\nobserverObj: ', observerObj)class Obj {
constructor(no) {
this.no = no
}
}
const observedObj = new Obj(1)
const observerObj = new Obj(1)
const handler = {
set(observed, key, value) {
if (key === 'no') {
observer(key, observed[key], value)
}
Reflect.set(observed, key, value)
}
}
const observerProxy = new Proxy(observedObj, handler)
function observer(key, oldVal, newVal) {
console.log(`observedObj的no属性值由${oldVal}变为${newVal}`)
observerObj[key] = newVal
}
observerProxy.no = 2
console.log('observedObj: ', observedObj, '\nobserverObj: ', observerObj)输出
observedObj的no属性值由1变为2
observedObj: Obj { no: 2 }
observerObj: Obj { no: 2 }observedObj的no属性值由1变为2
observedObj: Obj { no: 2 }
observerObj: Obj { no: 2 }
评论