一、proxy
proxy就是一个拦截器,拦截了原来的对象之后,可以对这个对象进行自己的更改,也可以防止别人对对象进行某种更改,然后可以输出修改后的monitor,且不影响原对象。
1 2 3 4 5 6
| { let obj = { time: '2017-03-11', name: 'net', _r: 123 }
|
1. proxy的声明
(1)可以声明后直接在handler里面写对象
1 2 3 4 5 6
| let proxy = new Proxy(obj,handler) handler = { get () {}, set () {}, has () {}, }
|
(2)下面这种声明方式
1 2 3
| let proxy = new Proxy(obj,{ get (target,key) {} })
|
2. get/set/has/等拦截方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41
| let monitor = new Proxy(obj,{ get (target,key) { if(target[key].replace) return target[key].replace('2017','2018') else return target[key] }, set (target,key,value) { if(key === 'name') { return target[key] == value } }, has (target,key) { if (key == '_r') { return false } else { return key in target } } })
console.log(monitor.time) monitor._r = 'sdffsfsdfds' console.log(monitor._r) monitor.name = 'sdffsfsdfds' console.log(monitor.name) console.log('name' in monitor) console.log('_r' in monitor) console.log('_r' in monitor) }
|
二、 reflect
(1) 名称和用法与proxy一样
(2) ES6 中将 Object 的一些明显属于语言内部的方法移植到了 Reflect 对象上(当前某些方法会同时存在于 Object 和 Reflect 对象上),未来的新方法会只部署在 Reflect 对象上。
(3) Reflect 对象对某些方法的返回结果进行了修改,使其更合理。
(4) Reflect 对象使用函数的方式实现了 Object 的命令式操作。
为什么用reflect,要尽量避免用原生的Object方法,通过Reflect方法调用会比较合理和方便。
1 2 3 4 5 6 7 8 9 10
| { let obj = { time: '2017-03-11', name: 'net', _r: 123 }
}
Reflect.get(obj,'name')
|
在vue3的源码中,原先的数据驱动视图的方法Object.defineProperty被替换成了Proxy来实现,在Proxy内部操作数据时就用了Reflect去调用对象方法。