当前位置:网站首页>Proxy and reflection (II)
Proxy and reflection (II)
2022-06-12 02:11:00 【Red blue purple】
Proxy and reflection ( Two )
There are some useful functions that can be implemented using the proxy pattern .
Capture operation
By adding a corresponding catcher , You can capture it get、set、has Wait for the operation , You can monitor when and where this object has been accessed , And can access 、 Do what you want to do before revision , And realize the original function again through reflection .
const user = {
name: 'clz'
}
const proxy = new Proxy(user, {
get(target, property, receiver) {
console.log(` visit ${
property}`)
return Reflect.get(...arguments)
},
set(target, property, value, receiver) {
console.log(` Set up ${
property}=${
value}`)
return Reflect.set(...arguments)
}
})
console.log(proxy.name)
proxy.age = 21

Here's a little bit of attention : The operation through the proxy object will be captured , Operations that directly manipulate the target object are not captured .
const user = {
name: 'clz'
}
const proxy = new Proxy(user, {
get(target, property, receiver) {
console.log(` visit ${
property}`)
return Reflect.get(...arguments)
}
})
console.log(proxy.name)
console.log(user.name)

Hidden attribute
Because the internal implementation of the proxy is invisible to the external code , So it is easy to hide the attributes on the target object . We said that above , The original function needs to be realized through reflection , But we can also not realize the original function , Instead, it returns other values .
const user = {
name: 'clz',
age: 21
};
const proxy = new Proxy(user, {
get(target, property, receiver) {
if (property === 'name') {
// hide name attribute
return undefined;
}
return Reflect.get(...arguments)
}
});
console.log(user)
console.log(user.name)
console.log(user.age)
console.log('%c%s', 'font-size:24px;color:red', '=================')
console.log(proxy)
console.log(proxy.name)
console.log(proxy.age)

From above , We can know , Direct access to the target object 、 Target object properties and access to proxy objects can achieve the same results . however , Access... Through a proxy name Property will get undefined, Because we have hidden attributes in the capture operation .
verification
Attribute validation
Because all assignment operations will trigger set Catcher , Therefore, you can decide whether to allow or reject the assignment according to the assigned value , Not verified , direct return false The assignment can be rejected .
const user = {
name: 'clz',
age: 21
};
const proxy = new Proxy(user, {
set(target, property, value) {
if (typeof value !== 'number') {
console.log(' No number type , Reject assignment ')
return false;
} else {
return Reflect.set(...arguments);
}
}
});
proxy.age = 999;
console.log(proxy.age);
proxy.age = '111';
console.log(proxy.age);

When we return false when , That is, it fails to pass the verification , You can avoid the implementation of the original behavior ,
Function parameter validation
Similar to validating object properties , You can also review the parameters of a function .
First , Functions can also use proxies .apply The catcher is called when the function is called .
function fn() {
}
const proxy = new Proxy(fn, {
apply() {
console.log(' Call function ')
}
});
proxy(1, 2, 3, 4, 5)
So we should apply Operation verification in the catcher .
function mysort(...nums) {
return nums.sort((a, b) => a - b);
}
// stay `apply` Parameter validation in the catcher
const proxy = new Proxy(mysort, {
apply(target, thisArg, argumentsList) {
// target: Target audience
// thisArg: When calling a function this Parameters
// argumentsList: List of parameters when calling a function
for (const arg of argumentsList) {
if (typeof arg !== 'number') {
throw ' Function arguments must be number';
}
}
return Reflect.apply(...arguments);
}
});
let fin = proxy(2, 1, 6, 3, 4, 3);
console.log(fin);
fin = proxy(2, 1, 'hello', 3, 4, 3);
console.log(fin);
The same goes for constructors , Only the constructor is passed through constructor Capture to implement the proxy .
function Person(name) {
this.name = name
}
const proxy = new Proxy(Person, {
construct() {
console.log(123)
return Reflect.construct(...arguments)
}
});
const p = new proxy('clz')
console.log(p)
Data binding
Through the agent, the irrelevant parts of the original operation can be linked together .
Example : Bind the proxied class to a global collection of instances , Add all the created instances to this collection .`
const userList = []
class User {
constructor(name) {
this.name_ = name;
}
}
const proxy = new Proxy(User, {
construct() {
const newUser = Reflect.construct(...arguments)
userList.push(newUser)
return newUser
}
})
new proxy('clz')
new proxy('czh')
console.log(userList)
Event distributor
Before we start , Let's start with a little question .
const nums = []
const proxy = new Proxy(nums, {
set(target, property, value, receiver) {
console.log('setting')
return Reflect.set(...arguments)
}
})
proxy.push(1)
The above code will be printed twice setting.
Why is that ?
Let's print out the attributes of each round of modification , Look at the .
const nums = []
const proxy = new Proxy(nums, {
set(target, property, value, receiver) {
console.log('setting')
console.log(property)
return Reflect.set(...arguments)
}
})
proxy.push(1)

We can find out , The first is 0, The second, length. in other words ,push It is actually divided into two stages , In the first round, modify the array first , The second round is to modify the array length , So it prints two rounds .( There is no authoritative explanation , The conclusion of the practical test , There are questions to comment on )
Back to the point : You can bind a collection to an event distributor , Each time a new instance is inserted , Will send messages .
const nums = []
function emit(newValue) {
console.log(' There's new data , The new data is ', newValue)
}
const proxy = new Proxy(nums, {
set(target, property, value, receiver) {
const result = Reflect.set(...arguments)
// Reflect.set return boolean value , This value indicates whether the property has been successfully set
if (result) {
// If it is set successfully , Call the event dispatch function , Pass the newly inserted value as a parameter
emit(Reflect.get(target, property, receiver))
}
return result
}
})
proxy.push(111)
proxy.push(222)
console.log(proxy)

You can find it here , We push Two pieces of data , But it will trigger the event distributor 4 Time , Why is that ?
This is what was said in this section ,push It is actually divided into two stages , In the first round, modify the array first , The second round is to modify the array length .
therefore , We should not just judge whether it has been successfully set up , You should also judge whether the attribute is length.
if (result && property !== 'length') {
// If it is set successfully , Call the event dispatch function , Pass the newly inserted value as a parameter
emit(Reflect.get(target, property, receiver))
}

边栏推荐
- leetcodeSQL:612. Nearest distance on plane
- 力扣解法汇总675-为高尔夫比赛砍树
- Force deduction solution summary -04.06 Successor
- 商城开发知识点
- Force deduction solution summary 713- subarray with product less than k
- Xcall cluster script (view JPS command)
- Force deduction solution summary 467- unique substring in surrounding string
- virsh创建/关闭/停止虚拟机常用的几条指令
- Implementation scheme of iteration and combination pattern for general tree structure
- xcall 集群脚本(查看jps命令)
猜你喜欢

Ozzanmation action system based on SSE

Master of a famous school has been working hard for 5 years. AI has no paper. How can the tutor free range?

Ozzanation - système d'action basé sur sse

阿里云oss文件上传系统

Is the bidding price fixed for each click?
![[adjustment] notice on the opening of the 2022 pre adjustment system for postgraduate enrollment of Shanghai Second University of Technology](/img/16/2f9a235995cdd54ac9b85a68a7afcb.jpg)
[adjustment] notice on the opening of the 2022 pre adjustment system for postgraduate enrollment of Shanghai Second University of Technology

MySQL table common operation mind map

el-upload上传文件

Graphic data analysis | data cleaning and pretreatment

RPA introduction
随机推荐
The most comprehensive redis transaction control in 2022 (with illustration)
Force deduction solution summary -04.06 Successor
How to stop anti-virus software from blocking a web page? Take gdata as an example
Wide match modifier symbol has been deprecated, do not use
[adjustment] notice on the opening of the 2022 pre adjustment system for postgraduate enrollment of Shanghai Second University of Technology
Alicloud OSS file upload system
Summary of force deduction solution 436- finding the right interval
Implementation scheme of iteration and combination pattern for general tree structure
力扣解法汇总462-最少移动次数使数组元素相等 II
力扣解法汇总-04.06. 后继者
The release of star ring kundb 2.2 provides a new choice for business systems with high concurrent transactions and queries
"China Dongxin Cup" the fourth programming competition of Guangxi University (synchronous competition)
Master of a famous school has been working hard for 5 years. AI has no paper. How can the tutor free range?
2022西式面点师(技师)复训题库及在线模拟考试
Oracle 11g graphic download installation tutorial (step by step)
Force deduction solution summary 713- subarray with product less than k
超图倾斜数据合并根节点后转3dtiles
Force deduction solution summary 883- projected area of 3D shape
Leetcode 55 jump game
力扣解法汇总1037-有效的回旋镖