Proxy Object in JavaScript

  • 2021-09-24 21:31:43
  • OfStack

Proxy Object in Js

Proxy objects are used to define custom behavior for basic operations, such as property lookups, assignments, enumerations, function calls, and so on.

Grammar


const proxy = new Proxy(target, handler);
target: The target object to be wrapped with Proxy can be any type of object, including a native array, a function, or even another proxy. handler: An object that usually has functions as attributes, and the functions in each attribute define the behavior of proxy proxy when performing various operations.

Describe

Proxy is used to modify the default behavior of some operations, which can also be understood as setting up a layer of interception before the target object, and all external accesses must pass through this layer of interception first, so it provides a mechanism to filter and modify external accesses. The principle of this word is proxy, which can mean that it proxies some operations, translated as proxy.


var target = {a: 1};
var proxy = new Proxy(target, {
  set: function(target, key, value, receiver){ 
    console.log("watch");
    return Reflect.set(target, key, value, receiver);
  },
  get: function(target, key, receiver){ 
    return target[key];
  }
});
proxy.a = 11; // watch
console.log(target); // {a: 11}

Object. defineProperty is used to listen to attributes, while Proxy is used to listen to the whole object. By calling new Proxy (), a proxy can be created to replace another object and be called a target. This proxy virtualizes the target object, so the proxy and the target object can be treated as the same object on the surface. Proxies allow you to intercept the underlying operations on the target object, This is originally the internal capability of Js engine, and the interception behavior uses a function that can respond to specific operations, that is, after an object is proxy through Proxy, we will get an object that is almost exactly the same as the proxy object, and this object can be completely monitored from the bottom.


//  Common 1 Road test questions   Realization  a===1&&a===2&&a===3  For true

// Object.defineProperty  What you define is an attribute 
//  The requirements for the topic can be realized 
var _a = 0;
Object.defineProperty(window, "a", {
  get:function(){
    return ++_a;
  }
})
console.log(a===1 && a===2 && a===3); // true

// proxy  Proxy is an object  
//  Therefore, when calling, it actually does not conform to the requirements of the topic 
//  But it is also 1 Kinds of implementation methods 
var _a = 0;
var proxy = new Proxy(window, {
  set: function(target, key, value, receiver){ 
    return Reflect.set(target, key, value, receiver);
  },
  get: function(target, key, receiver){
    if(key === "a") return ++_a;
    else return window[key];
  }
});
console.log(proxy.a===1 && proxy.a===2 && proxy.a===3); //true

Method

Proxy.revocable()

Proxy.revocable(target, handler)
The Proxy. revocable () method can be used to create a revocable proxy object that returns a revocable Proxy object that contains the proxy object itself and its revocable methods.

target: The target object to be encapsulated in Proxy can be any type of object, including native arrays, functions, or even another proxy object. handler: An object whose properties are a batch of optional functions that define the behavior of the agent when the corresponding operation is performed.

The return value of this method is an object with the structure {"proxy": proxy, "revoke": revoke}. Once a proxy object is undone, it will become almost completely uncallable, and any proxy operation performed on it will throw an TypeError exception. Note that there are 14 proxy operations 1, and no exception will be thrown when performing operations other than these 14 operations. Once undone, this proxy object cannot be directly restored to its original state, and its associated target object and processor object may be garbage collected. Calling the undo method revoke () again will have no effect, but it will not report an error.


var revocable = Proxy.revocable({}, {
 get: function(target, key) {
  return `[[ ${key} ]]`;
 }
});
var proxy = revocable.proxy;
console.log(proxy.example); // [[ example ]]
revocable.revoke();
// console.log(proxy.example); //  Throw  TypeError
// proxy.example = 1;      //  Throw  TypeError
// delete proxy.example;    //  Throw  TypeError
// typeof proxy         // "object" , because  typeof  Is not a proxy operation 

handler Object Method

The handler object is a placeholder object that holds a batch of specific properties and contains the individual captures of Proxy, trap. All traps are optional, and if no traps are defined, the default behavior of the source object is preserved.

handler. getPrototypeOf (): The catcher for the Object. getPrototypeOf method. handler. setPrototypeOf (): Catcher for Object. setPrototypeOf method. handler. isExtensible (): Catcher for the Object. isExtensible method. handler. preventExtensions (): The catcher for the Object. preventExtensions method. handler. getOwnPropertyDescriptor (): Catcher for Object. getOwnPropertyDescriptor method. handler. defineProperty (): Catcher for Object. defineProperty method. handler. has (): A catcher for the in operator. handler. get (): Catcher for property read operations. handler. set (): Catcher for property setting actions. handler. deleteProperty (): A catcher for the delete operator. handler. ownKeys (): Catcher for Reflect. ownKeys, Object. getOwnPropertyNames, Object. keys, Object. getOwnPropertySymbols methods. handler. apply (): Catcher for function call operations. handler. construct (): The catcher for the new operator.

var target = {
  a: 1,
  f: function(...args){
    console.log(...args);
  }
};
var proxy = new Proxy(target, {
  getPrototypeOf: function(target) {
    console.log("getPrototypeOf");
    return Object.getPrototypeOf(target);
  },
  setPrototypeOf: function(target, prototype) {
    console.log("setPrototypeOf");
    return Object.setPrototypeOf(target, prototype);
  },    
  isExtensible: function(target) {
    console.log("isExtensible");
    return Object.isExtensible(target);
  },
  preventExtensions: function(target) {
    console.log("preventExtensions");
    return Object.preventExtensions(target);
  },
  getOwnPropertyDescriptor: function(target, prop) {
    console.log("getOwnPropertyDescriptor");
    return Object.getOwnPropertyDescriptor(target, prop);
  },
  defineProperty: function(target, prop, descriptor) {
    console.log("defineProperty");
    return Object.defineProperty(target, prop, descriptor);
  },
  has: function(target, prop) {
    console.log("has");
    return prop in target;
  },
  get: function(target, prop, receiver) {
    console.log("get");
    return target[prop];
  },
  set: function(target, prop, value, receiver) {
    console.log("set");
    target[prop] = value;
    return true;
  },
  deleteProperty: function(target, property) {
    console.log("deleteProperty");
    delete target[property];
    return true;
  },
  ownKeys: function(target) {
    console.log("ownKeys");
    return Reflect.ownKeys(target);
  }
})


var proxyF = new Proxy(target.f, {
  construct: function(target, argumentsList, newTarget) {
    console.log("construct");
    return new target(...argumentsList);
  },
  apply: function(target, thisArg, argumentsList) {
    console.log("apply");
    return target.apply(thisArg, argumentsList);
  },

})

const _prototype = {test: 1};
Object.setPrototypeOf(proxy, _prototype); // setPrototypeOf
console.log(Object.getPrototypeOf(proxy)); // getPrototypeOf // { test: 1 }

Object.preventExtensions(proxy); // preventExtensions
console.log(Object.isExtensible(proxy)); // isExtensible // false

Object.defineProperty(proxy, "a", {configurable: true}); // defineProperty
console.log(Object.getOwnPropertyDescriptor(proxy, "a")); // getOwnPropertyDescriptor // { value: 1, writable: true, enumerable: true, configurable: true }

proxy.a = 11; // set
console.log(proxy.a); // get // 11

console.log(Object.keys(proxy)); // ownKeys getOwnPropertyDescriptor getOwnPropertyDescriptor // [ 'a', 'f' ]
delete proxy.a; // deleteProperty
console.log("a" in proxy); // has // false

proxyF(1, 2, 3); // apply 1 2 3
new proxyF(1, 2, 3); // construct 1 2 3

1 question per day

https://github.com/WindrunnerMax/EveryDay

These are the details of Proxy objects in JavaScript. For more information about JavaScript Proxy objects, please pay attention to other related articles on this site!


Related articles: