【笔记】JS的Proxy代理和Reflect反射

前言

JS通过Proxy代理实现拦截对象操作,并通过Reflect反射来操作对象

为对象创建对应的代理对象

1
2
3
4
5
const obj = {}

const objProxy = new Proxy(obj, {
...
})

操作对象改为操作对象的代理

1
2
// obj.key = "value";
objProxy.key = "value";

Proxy捕获器中通过Reflect反射操作对象

捕获对象读取属性操作

receriver:将当前代理对象作为原对象的this指向

1
2
3
4
5
6
7
8
9
10
const obj = { key: "value" };

const objProxy = new Proxy(obj, {
get: function (target, propertyKey, receriver) {
console.log(target, propertyKey, receriver);
return Reflect.get(target, propertyKey, receriver);
}
});

console.log(objProxy.key); // "value"

捕获对象写入属性操作

1
2
3
4
5
6
7
8
9
10
const obj = { key: "value" };

const objProxy = new Proxy(obj, {
set: function (target, propertyKey, value, receriver) {
console.log(target, propertyKey, value, receriver);
return Reflect.set(target, propertyKey, value, receriver);
}
});

objProxy.key = "value";

捕获对象删除属性操作

1
2
3
4
5
6
7
8
9
10
const obj = { key: "value" };

const objProxy = new Proxy(obj, {
deleteProperty: function (target, propertyKey) {
console.log(target, propertyKey);
return Reflect.deleteProperty(target, propertyKey);
}
});

delete objProxy.key;

捕获判断对象属性是否存在操作

1
2
3
4
5
6
7
8
9
10
const obj = { key: "value" };

const objProxy = new Proxy(obj, {
has: function (target, propertyKey) {
console.log(target, propertyKey);
return Reflect.has(target, propertyKey);
}
});

console.log("key" in objProxy);

捕获函数对象调用操作

1
2
3
4
5
6
7
8
9
10
const fn = function (key1, key2) {};

const fnProxy = new Proxy(fn, {
apply: function (target, thisArgument, argumentList) {
console.log(target, thisArgument, argumentList);
return Reflect.apply(target, thisArgument, argumentList);
}
});

fnProxy("value", "value");

捕获构造函数创建对象操作

1
2
3
4
5
6
7
8
9
10
const fn  = function (key1, key2) {};

const fnProxy = new Proxy(fn, {
construct: function (target, argumentList, newTarget) {
console.log(target, argumentList, newTarget);
return Reflect.construct(target, argumentList, newTarget);
}
});

new fnProxy("value", "value");

捕获对象获取原型对象操作

1
2
3
4
5
6
7
8
9
10
const obj = {};

const objProxy = new Proxy(obj, {
getPrototypeOf: function (target) {
console.log(target);
return Reflect.getPrototypeOf(target);
}
});

console.log(Object.getPrototypeOf(objProxy));

捕获对象修改原型对象操作

1
2
3
4
5
6
7
8
9
10
const obj = {};

const objProxy = new Proxy(obj, {
setPrototypeOf: function (target, prototype) {
console.log(target, prototype);
return Reflect.setPrototypeOf(target, prototype);
}
});

Object.setPrototypeOf(objProxy, null);

捕获判断对象是否可以新增属性操作

1
2
3
4
5
6
7
8
9
10
const obj = {};

const objProxy = new Proxy(obj, {
isExtensible: function (target) {
console.log(target);
return Reflect.isExtensible(target);
}
});

console.log(Object.isExtensible(objProxy));

捕获对象获取属性描述符操作

1
2
3
4
5
6
7
8
9
10
const obj = {};

const objProxy = new Proxy(obj, {
getOwnPropertyDescriptor: function (target) {
console.log(target);
return Reflect.getOwnPropertyDescriptor(target);
}
});

console.log(Object.getOwnPropertyDescriptor(objProxy));

捕获对象新增属性操作

1
2
3
4
5
6
7
8
9
10
const obj = {};

const objProxy = new Proxy(obj, {
defineProperty: function (target, propertyKey, attributes) {
console.log(target, propertyKey, attributes);
return Reflect.defineProperty(target, propertyKey, attributes);
}
});

Object.defineProperty(objProxy, "key", {});

捕获对象获取所有属性名操作

1
2
3
4
5
6
7
8
9
10
const obj = {};

const objProxy = new Proxy(obj, {
ownKeys: function (target) {
console.log(target);
return Reflect.ownKeys(target);
}
});

console.log(Object.keys(objProxy));

完成