proxy

基本使用

Proxy 在目标对象之前架设一层“拦截”,外界对该对象的访问和设置,都要先通过这层拦截,实现对外界的访问进行过滤和改写

new Proxy(target, handler) 接受两个参数

第一个参数是所要代理的目标对象,如果没有Proxy的介入,操作原来要访问的就是这个对象;

第二个参数是一个配置对象,对于每一个被代理的操作,需要提供一个对应的处理函数,该函数将拦截对应的操作

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
const obj = {}
const proxy = new Proxy(obj, {
get: function (target, propKey, receiver) {
console.log(`getting`);
console.log(target, 'get target');
console.log(propKey, 'get propKey');
console.log(receiver, 'get receiver');
},
set: function (target, propKey, value, receiver) {
console.log(`setting`);
console.log(target, 'set target');
console.log(propKey, 'set propKey');
console.log(value, 'set value');
console.log(receiver, 'set receiver');
}
});

obj.a = 3

proxy.b = 4

如果对 obj 直接赋值操作是无法触发拦截的。要使得Proxy起作用,必须针对Proxy实例进行操作

get 拦截

可以接受三个参数,依次为目标对象、属性名和 proxy 实例本身

get方法可以继承

1
2
3
4
5
6
7
8
9
let proto = new Proxy({}, {
get(target, propertyKey, receiver) {
console.log('GET ' + propertyKey);
return target[propertyKey];
}
});

let obj = Object.create(proto);
obj.foo

上面代码,拦截操作定义在Prototype对象上面,所以如果读取obj对象继承的属性时,拦截会生效

set

set方法用来拦截某个属性的赋值操作,可以接受四个参数,依次为目标对象、属性名、属性值和 Proxy 实例本身,其中最后一个参数可选

this 指向

在 Proxy 代理的情况下,目标对象内部的this关键字会指向 Proxy 代理

1
2
3
4
5
6
7
8
9
10
11
const target = {
m: function () {
console.log(this === proxy);
}
};
const handler = {};

const proxy = new Proxy(target, handler);

target.m() // false
proxy.m() // true

有些原生对象要正确的绑定this

1
2
3
4
5
6
7
8
9
10
11
12
const target = new Date('2015-01-01');
const handler = {
get(target, prop) {
if (prop === 'getDate') {
return target.getDate.bind(target);
}
return Reflect.get(target, prop);
}
};
const proxy = new Proxy(target, handler);

proxy.getDate() // 1

Proxy的13种方法与Reflect的方法是一一对应的

返回
顶部