Proxy catcher and reflection method

Keywords: Javascript node.js Vue.js

Proxy catcher and reflection method

Source JavaScript advanced programming

The agent can capture 13 different basic operations. These basic operations have their own reflection API methods, parameters, associated ECMAScript operations, and invariants.

get()

The get () catcher will be called in the operation of getting the property value. The method of the corresponding reflection API is Reflect.get()

// get()

const test1={
    name:'yihen'
}
const proxy=new Proxy(test1,{
    get(target,property,receiver){
        console.log('Already called get()')
        return Reflect.get(...arguments);
    }
})
//get() has already been called 
console.log(proxy.name);// yihen
  1. Return value

Unlimited return value

  1. Intercepted operation
  • proxy.property
  • proxy[property]
  • Object.create(proxy)[property]
  • Reflect.get(proxy,property,receiver)
  1. Catcher handler parameters
  • Target: target object
  • Property: the string key property on the referenced target object
  • receiver: a proxy object or an object that inherits a proxy object
  1. Catcher invariant
  • If target.property is not writable and configurable, the value returned by the handler must match target.property

  • If target.property is not configurable and the [[Get]] attribute is undefined, the return value of the handler must also be undefined

set()

The set () catcher is called in the operation of setting the property value. The corresponding reflection API method is Reflect.set()

const test2={}
const proxy2=new Proxy(test2,{
    set(target,property,value,receiver){
        console.log("Already called set()")
        const res=Reflect.set(...arguments);
        console.log(res);// true
        return res
    }
})

proxy2.name='yihen';// set() has already been called
console.log(test2.name); //yihen
  1. Return value
    Return true to indicate success; Returning false means failure. TypeError will be thrown in strict mode

  2. Intercept operation

  • proxy.property=value;
  • proxy[property]=value;
  • Object.create(proxy)[value];
  • Reflect.set(taget,property,value,receiver)
  1. Catcher handler parameters
  • Target: target object
  • Property: the string key property on the referenced target object
  • Value: the value to assign to the attribute
  • receiver: the object that receives the initial assignment
  1. Catcher invariant
  • If target.property is not writable and configurable, the property value of the target cannot be modified

  • If the target.property is not configurable and the [[Set]] attribute is undefined, the value of the target property cannot be modified. In strict mode, the handler will throw a TypeError if it returns false

has()

The has() catcher will be called in the in operator, and the corresponding reflection API method is Reflect.has();

/* 
has()
*/

const test3={}
const proxy3=new Proxy(test3,{
    has(target,property){
        console.log("You called has()")
        return Reflect.has(...arguments)
    }
})

console.log("name" in proxy3);// false
proxy3.name='yihen'
console.log("name" in proxy3);// true
  1. Return value
    has() must return a bool value, indicating whether the attribute exists. The returned non bool value will be converted to a bool value

  2. Intercept operation

  • property in proxy
  • property in Object.create(proxy)
  • with(proxy){(property);}
  • Reflect.has(proxy,property)
  1. Catcher handler parameters
  • Target: target object
  • Property: the string key property on the referenced target object
  1. Catcher invariant
  • If target.property exists and is not configurable, the handler must return true

  • If target.property exists and the target object is not extensible, the handler must return true

defineProperty

The defineProperty() catcher is called in Object.defineProperty(). The corresponding reflection API method is Reflect.defineProperty()

/* 
    defineProperty()
*/

const test4={}
const proxy4=new Proxy(test4,{
    defineProperty(target,property,descriptor){
        console.log('You called defineProperty');
        return Reflect.defineProperty(...arguments)
    }
});

Object.defineProperty(proxy4,'name',{
    value:'yihen'
});//You called defineProperty
  1. Return value

defineProperty() must return a bool value indicating whether the property was successfully defined. Returned non bool values are converted to bool values

  1. Intercept operation
  • Object.defineProperty(proxy,property,descriptor)
  • Reflect.defineProperty(proxy,property,descriptor)
  1. Catcher handler parameters
  • Target: target object
  • Property: the string key property on the referenced target object
  • descriptor: an object that contains optional enumerable, configurable, writable, value, get, and set definitions
  1. Catcher invariant
  • Properties cannot be defined if the target object is not extensible
  • If the target object has a configurable property, you cannot add a non configurable property with the same name
  • If the target object has a non configurable property, you cannot add a configurable property with the same name

getOwnPropertyDescriptor()

The getOwnPropertyDescriptor() catcher will be called in Object.getOwnPropertyDescriptor(). The corresponding reflection API method is Reflect.getOwnPropertyDescriptor()

/* 
    getOwnPropertyDescriptor()
*/

const test5={name:'yihen'}
const proxy5=new Proxy(test5,{
    getOwnPropertyDescriptor(target,property){
        console.log('You called getOwnPropertyDescriptor')
        return Reflect.getOwnPropertyDescriptor(...arguments)
    }
})

const res= Object.getOwnPropertyDescriptor(proxy5,'name') // 'you called getOwnPropertyDescriptor'
console.log(res)
/* 
{
  value: 'yihen',
  writable: true,
  enumerable: true,
  configurable: true
}
*/
  1. Return value
    getOwnPropertyDescriptor() must return an object or undefined if the property does not exist

  2. Intercepted operation

  • Object.getOwnpropertyDescriptor(proxy,property)
  • Reflect.getOwnPropertyDescriptor(proxy,property)
  1. Catcher handler parameters
  • Target: target object
  • Property: the string key property on the referenced target object
  1. Invariant of catcher
  • If its own target.property exists and is not configurable, the handler must return an object indicating the existence of the property

  • If its own target.property exists and can be configured, the handler must return an object indicating that the property exists and can be configured

  • If target.property does not exist and target is not extensible, the handler must return undefined to indicate that the property does not exist

  • If target.property does not exist, the handler cannot return an object indicating that the property is configurable

deleteProperty()

The deleteproperty () catcher is called in the delete operator. The corresponding reflection API method is Reflect.deleteProperty().

/* 
 deleteProperty()
*/


const test6={name:'yihen'}
const proxy6=new Proxy(test6,{
    deleteProperty(target,property){
        console.log('You called deleteProperty()')
        return Reflect.deleteProperty(...arguments)
    }
})
console.log(proxy6.name);// yihen
delete proxy6.name;
console.log(proxy6.name);// undefined
  1. Return value

The return value of deleteProperty() must be a bool value, indicating whether the property is deleted successfully. Returned non bool values are converted to bool values

  1. Intercept operation
  • delete proxy.property
  • delete proxy[property]
  • Reflect.deleteProperty(proxy,property)
  1. Catcher handler parameters
  • Target: target object
  • Property: the string key property on the referenced target object
  1. Catcher invariant

If the self owned target.property is not configurable, the processing function cannot delete this property

ownKeys()

The onwKeys() catcher will be called in Object.keys() and similar methods. The corresponding reflection API method is Reflect.ownKeys()

/* 
    ownKeys()
*/

const test7={name:'yihen',age:18}
Object.defineProperty(test7,'id',{
    value:12345678
})
const proxy7=new Proxy(test7,{
    ownKeys(target){
        console.log('You called ownKeys()')
        const res=Reflect.ownKeys(...arguments)
        console.log(res);// [ 'name', 'age','id ]
        return res
    }
})


const res2=Object.keys(proxy7)
console.log(res2);// [ 'name', 'age' ]
  1. Return value

ownKeys() must return an enumerable object containing a string or symbol

  1. Intercepted operation
  • Object.getOwnPropertyNames(proxy);
  • Object.getOwnPropertySymbols(proxy);
  • Object.keys(proxy);
  • Reflect.ownKeys(proxy)
  1. Catcher handler parameters

Target: target object

  1. Catcher invariant
  • The returned enumerable object must contain all non configurable own properties of target
  • If the target is not extensible, the returned enumerable object must accurately contain its own attribute key

getPrototypeOf()

The getPrototypeOf() catcher will be called in Object.getPrototypeOf(). The corresponding reflection API method is Reflect.getPrototypeOf().

/* 
 getPrototypeOf()
*/

const test8={}
const proxy8=new Proxy(test8,{
    getPrototypeOf(target){
        console.log("You called getPrototypeOf()")
        const res=Reflect.getPrototypeOf(...arguments);
        console.log(res);//[Object: null prototype] {}
        return res
    }
})

console.log(Object.getPrototypeOf(proxy8));//[Object: null prototype] {}
  1. Return value

getPrototypeOf() must return an object or null

  1. Intercepted operation
  • Object.getPrototypeOf(proxy);
  • proxy.__proro__
  • Object.prototypeOf.isPrototypeOf(proxy)
  • proxy instanceof Object
  • Reflect.getPrototypeOf(proxy)
  1. Capture handler parameters
  • Target: target object
  1. Capture invariant

If the target is not extensible, the only valid return value of Object.getPrototype(proxy) is the return value of Object.getPrototypeOf(target)

setPrototypeOf()

The setPrototypeOf() catcher will be called in Object.setPrototypeOf(), and the corresponding reflection API method is Reflect.setPrototypeOf()

/* 
    setPrototypeOf()
*/


const test9={}
const proxy9=new Proxy(test9,{
    setPrototypeOf(target,property){
        console.log('You called setPrototypeOf()')
        const res=Reflect.setPrototypeOf(...arguments);
        console.log(res); // true
        return res
    }
})

Object.setPrototypeOf(proxy9,Object);
  1. Return value

setPrototypeOf() must return bool value, indicating whether the prototype assignment is successful. The returned non bool value will be converted to bool value

  1. Intercepted operation
  • Object.setPrototypeOf(proxy)
  • Reflect.setPrototypeOf(proxy)
  1. Catcher handler parameters
  • Target: target object
  • Prototype: substitute prototype of target. null if it is a top-level prototype
  1. Catcher infinitive

If the target is not extensible, the only valid prototype parameter is Object.getPrototypeOf(target)

isExtensible()

The isExtensible() catcher is called in Object.isExtensible(). The corresponding reflection API method is Reflect.isExtensible().

const test1={}
const proxy1=new Proxy(test1,{
    isExtensible(target){
        console.log("Calling isExtensible()");
        const res=Reflect.isExtensible(...arguments);
        console.log(res);// true
        return res
    }
})

console.log(Object.isExtensible(proxy1));//true
  1. Return value
    isExtensible() must return a bool value indicating whether the target is extensible. Returned non bool values are converted to bool values.

  2. Intercepted operation

  • Object.isExtensible(proxy)
  • Reflect.isExtensible(proxy)
  1. Capture handler parameters
  • Target: target object
  1. Catcher invariant
  • If the target is extensible, it must return true
  • If the target is not extensible, false must be returned

preventExtensions()

The preventExtensions() catcher is called in Object.preventExtensions(). The corresponding reflection API method is Reflect.preventExtensions()

/* 
    preventExtensions()
*/

const test2={}
const proxy2=new Proxy(test2,{
    preventExtensions(target){
        console.log('You called preventExtensions()')
        const res=Reflect.preventExtensions(...arguments)
        console.log(res);// true
        return res
    }
})

console.log(Object.preventExtensions(proxy2));// {}
  1. Return value

preventExtensions() must return a bool value, indicating whether the target should not be extensible. The returned non bool value will be converted to a bool value

  1. Intercepted operation
  • Object.preventExtensions(proxy)
  • Reflect.preventExtensions(proxy)
  1. Catcher handler operation

target; Target object

  1. Capture its invariants

If Object.isExtensible(proxy) is false, the handler must return true

apply

The apply () catcher is called when the function is called. The corresponding reflection API method is Reflect.apply()

/* 
    apply()
*/

const test3=()=>{}
const proxy3=new Proxy(test3,{
    apply(target,thisArg,...argumentsList){
        console.log('You called apply()')
        const res=Reflect.apply(...arguments)
        console.log(res);// undefined
        return res
    }
})

proxy3()
  1. Return value

Unlimited return value

  1. Intercepted operation
  • proxy(...arguments)
  • Function.prototype.apply(thisArg,argumentsList)
  • Function.prototype.call(thisArg,...argumentsList)
  • Reflect.apply(target,thisArg,argumentsList)
  1. Catcher handler parameters
  • Target: target object
  • thisArg: this parameter when calling the function
  • argumentsList: list of arguments when calling a function
  1. Catcher invariant
  • target must be a function object

construct()

The construct () catcher is called in the new operator. The corresponding reflection API method is Reflect.construct()

/* 
    construct()
*/

const test4=function(){}
const proxy4=new Proxy(test4,{
    construct(target,argumentsList,newTarget){
        console.log('You called construct()');
        const res=Reflect.construct(...arguments)
        console.log(res);//test4 {}
        return res
    }
})

new proxy4;
  1. Return value

construct() must return an object

  1. Intercept operation
  • new proxy(...argumentsList)
  • Reflect.construct(target,argumentsList,newTarget)
  1. Catcher handler parameters
  • Target: target constructor
  • argumentsList: the list of arguments passed to the target constructor
  • newTarget: constructor originally called
  1. Catcher invariant

target must be available as a constructor

Posted by chordsoflife on Wed, 06 Oct 2021 10:09:18 -0700