1.什么是Proxy?它的作用是?
Proxy
可以理解成,在目标对象之前架设一层 "拦截
",当外界对该对象访问的时候,都必须经过这层拦截,而Proxy就充当了这种机制,类似于代理的含义,它可以对外界访问对象之前进行过滤和改写该对象
。
2.Proxy基本语法
const obj = new Proxy(target, handler)
被代理之后返回的对象 = new Proxy(被代理对象,要代理对象的操作)
handler中常用的对象方法如下:
get(target, propKey, receiver)
set(target, propKey, value, receiver)
has(target, propKey);//检测对象上是否有此属性
construct(target, args);//构造函数劫持,当通过new来调⽤代理的时候会触发contructor函数的执⾏
apply(target, object, args) //函数调⽤劫持,当通过代理执⾏函数的时候会触发apply函数的执⾏
例:set/get 设置、获取属性值劫持
let obj = {
name:'terry',
age:12
}
let proxy = new Proxy(obj, {
get:function(target,key){
return target[key]
},
set:function(target,key,value){
target[key] = value;
}
})
proxy.age = 13; // 将会触发set操作
console.log(proxy.name); // 将会触发get操作
3、vue3为什么要用proxy实现双向绑定?
(1) object.defineProperty的缺点:
因为es5的object.defineProperty无法监听对象属性的删除和添加
不能监听数组的变化,除了push/pop/shift/unshift/splice/spObject.definert/reverse,其他都不行
Object.defineProperty只能遍历对象属性直接修改(需要深拷贝进行修改)
(2) proxy的优点:
>1、直接监听对象而非属性
>2、直接监听数组的变化
>3、拦截的方式有很多种(有13种,set,get,has)
>4、Proxy返回一个新对象,可以操作新对象达到目的
(3) proxy的缺点:
proxy有兼容性问题,不能用polyfill来兼容(polyfill主要抚平不同浏览器之间对js实现的差异)
4、实现Vue3双向绑定
<body>
<h2 id="app"></h2>
<input id="input" type="text" />
</body>
let app = document.getElementById('app')
let input = document.getElementById('input')
let obj = { // 源数据
text:'hello world'
}
let proxy = new Proxy(obj, {
set: function(target, prop, value){ // input事件触发进行劫持,触发update方法
target[prop] = value
update(value)
}
})
function update(value){ // update方法用于同步dom更新
app.innerHTML = value
input.value = value
}
input.addEventListener('input',function(e){ // 监听input数据变化,并修改proxy的值
proxy.text = e.target.value
})
proxy.text = obj.text // 初始化源数据