Definition
Proxy objects are used to define custom behaviors for basic operations (such as attribute lookup, assignment, enumeration, function call, etc.).
grammar
let p = new Proxy(target, handler);
parameter
target: target objects that need to be wrapped in Proxy
handler: A function that defines the behavior of a proxy
folk understanding
In fact, it is to intercept the target object to filter and rewrite it, so that the object can be manipulated indirectly through the proxy object instead of directly manipulating the object itself.
Proxy operations in handler objects
1,apply(target, thisArg, argumentsList)
Used to intercept function calls, triggered when the target target is a function and is called.
function sum(a, b) { return a + b; } const handler = { apply: function(target, thisArg, argumentsList) { //Target is the target object sum function //This Arg binds this object when the target function is called //argumentsList is an array of target object parameters [1,2] console.log(`Calculate sum: ${argumentsList}`); return target(argumentsList[0], argumentsList[1]) * 10; } }; var proxy1 = new Proxy(sum, handler); console.log(proxy1(1, 2));
2,construct(target, argumentsList, newTarget)
Triggered to intercept the new operator and construct an instance of a proxy object whose target is a constructor
function monster1(disposition) { this.disposition = disposition; } const handler1 = { construct(target, args) { //args is the passed parameter for instantiation ['fierce'] return new target(...args); } }; const proxy1 = new Proxy(monster1, handler1); console.log(new proxy1('fierce').disposition);
Example
1. Basic examples
let obj = { a : 1 } let proxyObj = new Proxy(obj,{ get : function (target,key) { return key in target ? target[key] : 0 }, set : function (target,key,value) { target[key] = 888; } }) console.log(proxyObj.a); // 1 console.log(proxyObj.b); // 0 proxyObj.a = 666; console.log(proxyObj.a) // 888
2. Operationless Forwarding Agent
let target = {}; let p = new Proxy(target, {}); p.a = 37; // Operations are forwarded to the target console.log(target.a); // 37. The operation has been forwarded correctly
3. Validation of Data Legitimacy
let validator = { set: function(obj, key, value) { if (key === 'age') { if (!Number.isInteger(value)) {//Number.isInteger(value) determines whether a number is an integer throw new TypeError('The age is not an integer'); } if (value > 200) { throw new RangeError('The age seems invalid'); } } // The default behavior to store the value obj[key] = value; } }; let person = new Proxy({}, validator); person.age = 100; console.log(person.age);// 100 person.age = 'young';// Throw an exception: Uncaught TypeError: The age is not an integer person.age = 300;// Throw an exception: Uncaught RangeError: The age seems invalid
4. Extended constructor
function extend(sup,base) { var descriptor = Object.getOwnPropertyDescriptor(//Returns the attribute descriptor corresponding to the target object's own attribute //configurable enumerable value writable base.prototype,"constructor" ); base.prototype = Object.create(sup.prototype); //new Object() creates objects through constructors, adding attributes under its own instance. //Object. create (proto, [propertiesObject]) Another way of creating objects in ES6 can be understood as inheriting an object and adding attributes under the prototype. //proto: Must. Represents the prototype object of a new object, that is, the parameter is assigned to the prototype of the target object. //ProperrtiesObject is optional. Attribute descriptors for enumerable attribute objects added to newly created objects and corresponding attribute names. //eg:var o = Object.create({}, { p: { value: 42 } }) var handler = { construct: function(target, args) { var obj = Object.create(base.prototype); this.apply(target,obj,args); return obj; }, apply: function(target, that, args) { sup.apply(that,args); base.apply(that,args); } }; var proxy = new Proxy(base,handler); descriptor.value = proxy; Object.defineProperty(base.prototype, "constructor", descriptor); return proxy; } var Person = function(name){ this.name = name }; var Boy = extend(Person, function(name, age) { this.age = age; }); Boy.prototype.sex = "M"; var Peter = new Boy("Peter", 13); console.log(Peter.sex); // "M" console.log(Peter.name); // "Peter" console.log(Peter.age); // 13