ES6语法中新增了一个Proxy类,名字的意思为代理,在实际使用中,通常用于监听对某个对象的操作,例如:获取属性值,设置属性值、对属性值进行修改等等。这个类相当用来管理对象的操作,里面定义的方法,可以对应上对象的操作,当操作Proxy实例对象时,可以重新定义操作的逻辑,当然,如果自己不重新定义就是默认的。在对象的操作方法里面,建议使用ES6新增的Reflect,而Reflect里定义了对象操作的方法,利用Reflect可以方便地对被代理对象的操作。例如:要修改获取一个对象的属性:
let object = { a: 1}
let proxy = new Proxy(object, {
get(target, key, receiver) {
console.log('ha ha ')
return Reflect.get(target, key)
}
})
上面的例子,在用点语法获取proxy的属性时,会进入到get方法,上面先输入“ha ha”,然后返回object的属性的值。
为了加深对Proxy的记忆,我尝试用Proxy写一个简单的观察者,下面我就分享一下自己写的dome:
首先创建一个观察者的类,放在Observer.js文件里:
class Observer {
createObserve(object) { //创建观察的对象
return new Proxy(object, {
set: (target, key, value, receiver) => {
Reflect.set(target, key, value, receiver)
this.action(target, key, value)
return true
}
})
}
action() {} //发生改变后执行的方法
}
window.Observer = Observer
写一个HTML文件
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Observer</title>
</head>
<body>
<div observe="data">
<span>姓名:</span>
<span>{{data.name}}</span>
<span>年龄:</span>
<span>{{data.age}}</span>
</div>
<script src="./Observer.js"></script>
<script>
function $(selector) {
return document.querySelector(selector)
}
function setTemplate(dom) { //修改模板
function changeValue(str, ...values) {
return str.reduce((a, b, index) => {
return a + b + (values[index] || '')
}, '')
}
dom.template || (dom.template = dom.innerHTML)
let template = dom.template.replace(/{{/g, '${').replace(/}}/g, '}')
let changeFunc = `changeValue\`${template}\``
dom.innerHTML = eval(changeFunc)
}
let observer = new Observer()
observer.action = (target, key, value) => { //重定义改变属性后执行的方法
setTemplate($('[observe="data"]'))
}
let data = observer.createObserve({
name: '小明',
age: 16
})
setTemplate($('[observe="data"]'))
setTimeout(() => {
data.age = 17
data.name = '明明'
}, 2000)
</script>
</body>
</html>
上面代码可以在观察data的值发生改变时,html上的用来data的内容随着改变。简单的观察者模式,就此实现。