定义:Proxy 对象用于定义基本操作的自定义行为(如属性查找,赋值,枚举,函数调用等)。
语法:
let p = new Proxy(target, handler);
参数:
target
用Proxy包装的目标对象(可以是任何类型的对象,包括原生数组,函数,甚至另一个代理)。
handler
一个对象,其属性是当执行一个操作时定义代理的行为的函数。
基础示例
在以下简单的例子中,当对象中不存在属性名时,缺省返回数为37。例子中使用了 get
let handler = {
get: function(target, name){
return name in target ? target[name] : 37;
}
};
let p = new Proxy({}, handler);
p.a = 1;
p.b = undefined;
console.log(p.a, p.b); // 1, undefined
console.log('c' in p, p.c); // false, 37
无操作转发代理
在以下例子中,我们使用了一个原生 JavaScript 对象,代理会将所有应用到它的操作转发到这个对象上。
//原始对象
let target = {};
//代理对象
let p = new Proxy(target, {});
p.a = 37; // 操作转发到目标
console.log(target.a); // 37. 代理对象操作已经被正确地转发到原始对象
Proxy的基本方法
{
//原始对象
let days = Symbol.for('day');
let obj = {
time: '2019-11-3',
name: 'new',
_r: 123,
[days]: '7'
};
//代理对象 --映射obj
let monitor = new Proxy(obj, {
//拦截对象对属性的读取
get(target, key) {
return target[key].replace('2019', '2020');
},
//拦截对象设置属性
set(target, key, value) {
//只允许修改指定的属性
if(key === 'name') {
return target[key] = value;
} else {
return target[key];
}
},
//拦截key in object操作
//只允许查找指定属性
has(target, key) {
if(key === 'name') {
return target[key];
} else {
return false;
}
},
//拦截delete
deleteProperty(target, key) {
//允许删除开头是下划线的属性
if(key.indexOf('_') > -1) {
//删除属性
delete target[key];
return true;
} else {
return target[key];
}
},
// ownkeys()可拦截 Object.kes, Object.getOwnPropertySymbols,Object.getOwnPropertyNames
ownKeys(target) {
//起过滤作用,time被保护起来
return Object.keys(target).filter(item => item != 'time');
},
});
//通过Proxy对象拦截对原始数据的读取
console.log('get', monitor.time); //get 2020-11-3
//设定了只能修改原始对象obj的name属性
monitor.time = '2100';
monitor.name = 'wu';
console.log('set',monitor); //set Proxy {time: "2019-11-3", name: "wu", _r: 123, Symbol(day): "7"}
console.log('set',obj); //set {time: "2019-11-3", name: "wu", _r: 123, Symbol(day): "7"}
//判断对象是否存在指定属性
//monitor代理对象设置了'time'属性不能被外部访问
console.log('has','name' in monitor,'time' in monitor);//has true false
console.log('has','name' in obj,'time' in obj);//has true true
//删除指定的属性能否删除 需看Proxy设置中是否允许删除该属性
// delete monitor.time;
// console.log('delete',monitor); // {time: "2017-03-11", name: "mukewang", _r: 123}
// delete monitor._r;
// console.log('delete',monitor); // {time: "2017-03-11", name: "mukewang"}
//time属性被保护起来
console.log('ownKeys',Object.keys(monitor)); //ownKeys ["name", "_r"]
console.log('getOwnPropertyNames',Object.getOwnPropertyNames(monitor)); //getOwnPropertyNames ["name", "_r"]
}
总结:以上是ES6中Proxy代理对象的基本用法,可以看出其作用在于保护原始对象的数据,外部的访问操作只能和Proxy代理对象打交道,可根据自己实际的业务制定适合的拦截。接下来可能会对Proxy对象中的各种拦截方法进行进一步,详细的研究。(博主最近忙着想找实习了,笔试还行面试老是遇挫,但还是争取每日一更,也希望大家看到有错误的,欢迎提出,一起进步!)