Analysis of Proxy in ES6

Keywords: Attribute

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

Posted by livepjam on Sat, 05 Oct 2019 23:49:07 -0700