Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it possible to create a "before writing" Proxy for a Node.JS object?

Given an object like:

var box = { number: 20 }

I would like to tie a "before writing" Proxy (or equivalent) to it. This proxy would act as a middleware and perform a type-check.

For example, after doing box.number = "30" It would verify that typeof === "number". Since it is not, it would show an error.

Doing box.number = 30 would not trigger the proxy.


What I've tried:

  • This. Works only for undefined properties.
  • Watcher.JS The value gets written and then the middleware is executed (because it is a watcher). The middleware should execute first.

What I know that can be done:

  • I know that I can simply check the typeof of the variable beforehand. I am looking for a Proxy solution.
  • Custom defined functions (getters & setters). I would like to experiment with proxies, all properties have dynamic names.
like image 702
adelriosantiago Avatar asked Mar 09 '26 20:03

adelriosantiago


1 Answers

In my opinion, and consdering your needs, get/set is a better approach, they are faster in execution time, and the code is easier to mantain.

GETTERS/SETTERS SOLUTION

Are arround since the arrival of ES5...

  • A getter is a method that gets the value of a specific property.
  • A setter is a method that sets the value of a specific property.

You can define getters and setters on any predefined core object or user-defined object that supports the addition of new properties. The syntax for defining getters and setters uses the object literal syntax.

+info : https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Working_with_Objects

var box = { 
    _number : 0,
    get number(){ return this._number },
    set number(value){ 
        /* your verifications here */
        if( typeof value !== 'number' ) throw new Error('Invalid input')
        /* if validates , asign value */
        this._number = value;
    }
}
// test...
box.number = "1234"; // FAIL
box.number = 1234;   // OK
box.number;          // output = 1234

PROXY SOLUTION

Available since ES6. Probably not appropiate if performance is important for you. Use the GET/SET proxy traps, to obtain the same behavior as in the previous example.

// your original object...
var box = {};
// create a proxy linked to your original object
var boxProxy = new Proxy( box , {
    get( obj, prop, receiver ){ return obj[prop] },
    set( obj, prop, value){ 
        /* check if the property trying to be written is 'number' */
        if( prop === 'number' ){
             /* your verifications here */
            if( typeof value  !== 'number' ) throw new Error('Invalid input')
            /* if validates , asign value */
            this._number = value;
        }
    } 
 });
// test...
boxProxy.number = "1234"; // FAIL
boxProxy.number = 1234;   // OK
boxProxy.number;          // output = 1234

In both cases, if you require the propery box._number to be private and hidden you may implement it, using closures.

like image 176
colxi Avatar answered Mar 12 '26 10:03

colxi



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!