ES6新增Proxy对象用于定义基本操作的自定义行为(如属性查找,赋值,枚举,函数调用等)。
语法
/*
参数1: 用Proxy包装的目标对象(可以是任何类型的对象,包括原生数组,函数,甚至另一个代理)。
参数2: 一个对象,其属性是当执行一个操作时定义代理的行为的函数。(操作时的具体)
*/
const proxy = new Proxy(targe, handler)
栗子
const obj = {
firstName: 'JOJO',
age: 18,
children: {
obj2: {
firstName: '鸡哥'
},
obj3: {
firstName: '坤坤'
}
},
hobby: ['吃饭', '睡觉'],
}
const handler = {
// 参数3: Proxy 或者继承 Proxy 的对象
get(obj, key, receiver) {
return key in obj ? obj[key] : '没有'
},
set(obj, key val) {
obj[key] = val
},
/*
除了 get set proxy 还提供多种拦截操作
*/
/*
handler.has() 方法是针对 in 操作符的代理方法。
console.log('firstName' in proxy) false
*/
has(obj, key) {
if(key === 'firstName') {
return false
}
},
/*
handler.ownKeys() 方法用于拦截 Reflect.ownKeys()
Reflect.ownKeys() 返回一个由目标对象自身的属性键组成的数组
for (const key in proxy) {
console.log(key); // age
}
*/
ownKeys(obj) {
return Reflect.ownKeys(obj).filter(key => key === 'age');
}
}
深度侦听
function ob (obj) {
const handler = {
get (obj, key, receiver) {
if (typeof obj[key] === 'object') return new Proxy(obj[key], handler);
console.log('get', key, obj[key]);
return key in obj ? obj[key] : 'undefined';
},
set (obj, key, value) {
if (typeof value === 'object') return new Proxy(value, handler);
console.log('set', key, value);
obj[key] = value;
}
};
return new Proxy(obj, handler);
}