Sorting out common interception operation methods of Proxy instances

Keywords: Javascript Front-end Proxy

preface

Hello, guys. In the previous article, we briefly shared the Proxy in ES6. Through learning, we know that Proxy can intercept objects, so we can do some corresponding logical processing according to business needs. We also know that Vue3.0 makes a great optimization for data hijacking, in which Proxy is used. At the end of the article, we also sort out some instance methods that support interception provided by Proxy. In this chapter, we will share several common interception methods.

get(target, propKey, receiver)

Everyone who has read the previous article should notice that the most commonly used interception methods in our code cases are get and set. However, there is no detailed description of these methods.

  • The get(target, propKey, receiver) method is used to intercept the reading of the object's properties, that is, when we access the object's properties through the Proxy instance, we will first enter the get method.
  • The get method receives three parameters: target: the target object to be intercepted, propKey: the attribute in the target object, receiver (optional): the Proxy instance itself (strictly speaking, it should be the object targeted by the operation behavior). The third parameter uses few scenarios. Generally, the first two parameters are more.
  • The get method can support inheritance. It will be demonstrated with a small case.
let obj = {name:'Yannis'}
let proxy = new Proxy(obj,{
	get(target, key, receiver){
		console.log(target);
		console.log(key);
		return 'Hello '+ target[key];
	}
});

obj.name;
// {name:'Yannis'} target object to intercept
// name key: the attribute of the object being accessed
// 'Hello Yannis' when we access object properties, the interceptor automatically adds a Hello prefix

//  The get method can support inheritance
let proxy = new Proxy({},{
	get(target,key){
		return 'Hello Proxy'
	}
});
let obj = Object.create(proxy);
obj.name;//'Hello Proxy'
obj.age;//'Hello Proxy'
//Obj itself does not have these two properties, but because it inherits proxy, it will go to the get method of proxy. Therefore, no matter what properties of obj are accessed, it will always return 'Hello Proxy'

//  The third parameter of the get method
let obj = {name:'Yannis'}
let proxy = new Proxy({},{
	get(target, key, receiver){
		return receiver;
	}
});
proxy.name === proxy;//true
//Here, we directly return the third parameter in get. When accessing the object properties through the proxy instance, we find that the object properties are equal to the proxy instance. This also confirms the statement that the third parameter is the proxy instance itself

set(target, key, value)

Proxy's set method is also a commonly used interception method.

  • The set method is mainly used to intercept the setting of object properties, that is, when we assign values to object properties through Proxy instances, we will enter the set interception. This method returns a Boolean value
  • The set method receives four parameters: target: the intercepted target object, propKey: the attribute of the target object, value: the new value to be set for the target attribute, receiver (optional): the Proxy instance itself
  • The set method is mostly used to verify the validity of attributes or add some additional processing logic.
//If the Person object has an age attribute, the age should be a number and should not be too large or too small. When the user enters the age, we can use the set method to intercept and verify
let person = {age: 1}
let proxy = new Proxy(person,{
	set(target,key,value){
		//Only the age attribute is processed
		if(key === 'age'){
			if(!Number.isInteget(value)){
				throw new TypeError('The age is not an integer')
			}
			if(value<=0 || value>150){
				throw new RangeError('The age is incorrect')
			}
		}
		target[key] = value;//Assign the new value to the key attribute of target
		return true;
	}
})
person.age = 50;//true
person.age='Yannis';//report errors
person.age = 200;//report errors

has(target, key)

The has() method is used to intercept the HasProperty operation, that is, this method will take effect when determining whether an object has a property. A typical operation is the in operator.

  • The has method receives two parameters: target: target object, key: attribute name to be queried, and the return value is Boolean
  • The has method intercepts the HasProperty operation rather than the HasOwnProperty operation, that is, the has method does not judge whether a property is its own property or an inherited property
  • The has method interception does not take effect on the for... in loop
// Some properties of hidden objects are not found by in, such as underlined properties
let obj = {
	_a:'a',
	_b:'b',
	c:'c',
	d:'d'
}
let proxy = new Proxy(obj,{
	has(target,key){
		if(key[0] === '_'){
			return false
		}
		return key in target;
	}
})

'_a' in proxy;//false
'_b' in proxy;//false
'c' in proxy;//true
'd' in proxy;//true

ownKeys(target)

The ownKeys method is similar to the has method and is related to the operation of object properties, but ownKeys is used to intercept the method of obtaining object properties. It mainly intercepts the following methods to obtain attributes:

  • Object.getOwnPropertyNames(proxy)
  • Object.getOwnPropertySymbols(proxy)
  • Object.keys(proxy)
  • for... in loop
  • This method returns an array. The element of the array is the attribute name of all its own attributes of the object, and the return result of Object.keys() only includes the traversable attributes of the target object itself.
  • The ownKeys method only receives a parameter target, the target object to be intercepted

In addition, it should be noted that when using the Object.keys() method, three types of attributes will be automatically filtered by the ownKeys method

  • Property that does not exist on the target object
  • The property name is a value of type Symbol
  • Non traversable attribute (enumerable is false)
//Or take the underline attribute of hidden objects as an example
let obj= {
  _a: 'a',
  _b: 'b',
  c: 'c',
  d: 'd'
};
let proxy = new Proxy(obj, {
	 ownKeys (target) {
    	return Reflect.ownKeys(target).filter(key => key[0] !== '_');
  	}
});
for (let key of Object.keys(proxy)) {
  console.log(key);
}
// c
// d

deleteProperty(target, propKey)

The deleteProperty method is used to intercept the operation of deleting properties. The return value is Boolean. If the method throws an error or returns false, the current property cannot be deleted by the delete command.

  • This method receives two parameters: target object and propKey: attribute name corresponding to the object
//Or take the underline attribute of an object as an example
let obj= {
  _a: 'a',
  _b: 'b',
  c: 'c',
  d: 'd'
};
let proxy = new Proxy(obj, {
	 deleteProperty(target, key) {
    	if(key[0] === '_'){
    		throw new Error('Can not delete the private property')
    	}
    	delete target[key]
    	return true;
  	}
});
delete proxy['c'];// true
delete proxy['_a'];// Error: Can not delete the private property

summary

Here are some common interception methods for Proxy instances. Personally, I think the two methods most used are get and set. In addition to the above methods, there are many interception methods. Interested partners can explore them by themselves in combination with the arrangement of the previous article.

Like the little partner, welcome to like the message and pay attention!

Posted by bache on Fri, 22 Oct 2021 01:30:05 -0700