解释
proxy(代理)确切点说是拦截,在目标对象的外层搭建一层拦截
用法
proxy: 代理
target:目标对象
handler:用来指定拦截行为(也是一个对象)
var target = {
name:'zs',
age: 12
}
var handler = {
//当target被读取时自动触发该函数
get: (target,key) => {
console.log(`${key}被读取了`);
return target[key];
},
set: (target,key,value) => {
console.log(`${key}被设置为${value}`);
target[key] = value;
}
}
var proxy = new Proxy(target,handler);
console.log(proxy.name); //name读取了 zs
proxy.age = 18; //age被设置为18
应用
实现私有变量
实现拦截
var target = {
name: 'zs',
age: 12
}
var handler = {
get: (target,key) => {
if (key === 'age') {
console.log('私有变量age不能被访问')
return 18
}
}
}
var p = new Proxy(target,handler);
console.log(p.age); // 私有变量age不能被访问 18
Object.defineProperty()与Proxy的异同
vue2.0通过Object.defineProperty()实现数据的双向绑定,vue3.0通过proxy实现数据的双向绑定
(通过对对象的递归遍历,设置get,set方法,实现数据的双向绑定)
defineProperty的缺点::无法监控到数组下标的变化,导致直接通过数组的下标给数组设置值,不能实时响应(虽说对常用的方法进行了处理,但然存在局限性);只能劫持对象的属性(数组的方法,如push,pop,和有关下标的操作,都不能很好的监视),而proxy很好的解决了这个问题
Object.defineProperty()
push,pop,和有关下标的操作,都不能很好的监视
var obj = {};
Object.defineProperty(obj, 'a', {
get: () => {
console.log('get');
return v;
},
set: (value) => {
console.log('set');
v = value;
}
})
obj.a = []; //set
console.log(obj.a); //get []
obj.a.push('1') //get
obj.a[0] = 1 // get
obj.a.pop(1) // get
obj.a = [1, 2, 3] //set
Proxy 可以很好的监视数组的各种方法
var arr = [];
var handler = {
get: (target, key) => {
console.log('get');
return key in target ? target[key] : undefined
},
set: (target, key, value) => {
console.log('set');
target[key] = value
return true;
}
}
var p = new Proxy(arr, handler);
p.push(1);
//get 获取数组arr的push方法
//get 获取数组arr的length属性
//set 设置arr[0] = 1
//set 设置数组arr长度为1