Proxy
TIP
Proxy 对象用于创建一个对象的代理,从而实现基本操作的拦截和自定义(如属性查找、赋值、枚举、函数调用等)。
handler
TIP
包含捕捉器(trap)的占位符对象,可译为处理器对象。
handler.apply()
TIP
handler.apply()
方法用于拦截函数的调用。 参数: 以下是传递给apply方法的参数,this上下文绑定在handler对象上.
target
- 目标对象(函数)
thisArg
- 被调用时得上下文对象
argumentsList
- 被调用时得参数数组
示例:
const sum = (a, b) => a + b;
const handler = {
apply(target, thisArg, argumentsList) {
console.log(target, thisArg, argumentsList,'target, thisArg, argumentsList')
return '我是经过Proxy handler.apply处理后得'
},
};
const proxy = new Proxy(sum, handler);
console.log(proxy(1, 2),'proxy'); // 我是经过Proxy handler.apply处理后得 proxy
console.log(sum(1,2), 'sum') // 3 'sum'
约束:
TIP
如果违反了以下约束,代理将抛出一个TypeError:
- target必须是可被调用的。也就是说,它必须是一个函数对象。
handler.construct()
TIP
handler.construct() 方法用于拦截new 操作符. 为了使new操作符在生成的Proxy对象上生效,用于初始化代理的目标对象自身必须具有[[Construct]]内部方法(即 new target 必须是有效的)。
参数:
TIP
下面的参数将会传递给construct方法,this绑定在handler上。
target
- 目标对象
argumentsList
- constructor得参数列表
newTarget
- 最初被调用的构造函数
返回值:
- construct 方法必须返回一个对象。
描述:
handler.construct()
方法用于拦截 new操作符。
约束:
- 必须返回一个对象
示例:
function P(...args) {
this.args = args;
console.log(this.args,'this.args');
};
const handler = {
construct(target, argumentsList, newTarget) {
console.log(target, argumentsList, newTarget,'target, argumentsList, newTarget');
return new target(...argumentsList)
},
};
const P1 = new Proxy(P, handler)
console.log(new P1(1,2), 'construct'); // {name: 1} 'construct'
handler.get()
TIP
方法用于拦截对象的读取属性操作。
参数:
TIP
以下是传递给get方法的参数,this上下文绑定在handler对象上.
target
- 目标对象
property
- 被获取得属性名
receiver
Proxy
或者继承Proxy
得对象
返回值
get
方法可以返回任何值
约束
WARNING
如果违背了以下的约束,proxy会抛出 TypeError:
- 如果要访问的目标属性是不可写以及不可配置的,则返回的值必须与该目标属性的值相同。
- 如果要访问的目标属性没有配置访问方法,即get方法是undefined的,则返回值必须为undefined。
示例:
const obj = {name: '初始化'};
const handler = {
get(target, prop, receiver) {
console.log(target, prop, receiver, 'target, prop, receiver,')
return '我是Proxy handler.get()处理返回得'
},
};
const proxy = new Proxy(obj, handler);
console.log(proxy.name, 'proxy.name')
handler.has()
TIP
handler.has()
方法是针对 in
操作符的代理方法。
参数:
TIP
下面是传递给 has
方法的参数
target
- 目标对象
prop
- 需要检查是否存在得属性
返回值
TIP
has
方法返回一个boolean
属性得值
约束
WARNING
如果违反了下面这些规则, proxy
将会抛出 TypeError:
- 如果目标对象的某一属性本身不可被配置,则该属性不能够被代理隐藏.
- 如果目标对象为不可扩展对象,则该对象的属性不能够被代理隐藏
示例
const obj = {
name: 123
};
const handler = {
has(target, prop) {
console.log(target, prop,'target, prop');
return prop in target;
},
};
const proxy = new Proxy(obj, handler);
console.log('name' in proxy);
console.log('age' in proxy);
handler.set()
TIP
handler.set()
方法是设置属性值操作的捕获器。
参数:
TIP
以下是传递给 set()
方法的参数。this
绑定在 handler
对象上。
target
- 目标对象
proerty
- 将被设置得属性名
value
- 新属性值
receiver
- 最初被调用的对象。通常是 proxy 本身,但 handler 的 set 方法也有可能在原型链上,或以其他方式被间接地调用(因此不一定是 proxy 本身)。
返回值
TIP
set()
方法应当返回一个布尔值
- 返回 true 代表属性设置成功。
- 在严格模式下,如果 set() 方法返回 false,那么会抛出一个 TypeError 异常。
约束
WARNING
如果违背以下的约束条件,proxy 会抛出一个 TypeError 异常:
- 若目标属性是一个不可写及不可配置的数据属性,则不能改变它的值;
- 如果目标属性没有配置存储方法,即 [[Set]] 属性的是 undefined,则不能设置它的值。
- 在严格模式下,如果 set() 方法返回 false,那么也会抛出一个 TypeError 异常。
示例
const obj = {};
const handler = {
set(target, prop, value, receiver) {
console.log(target, prop, value, receiver,'target, prop, value, receiver');
target[prop] = '我是Proxy handler.set()设置得';
return true;
}
};
const proxy = new Proxy(obj, handler);
proxy.name = '小明';
console.log(obj);