3

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.
1
  • Use a CRUD method with get/set function, you can perform any checks before setting the actual value, and return true/false based on the result. Commented Jan 15, 2018 at 9:25

2 Answers 2

2

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.

Sign up to request clarification or add additional context in comments.

Comments

1

Here is an example, you have a verification code, and a default value

var box =Object.create({},{
number: {    
    get: function() { return this._number || 0; },
    set: function(value) {
      if(typeof value!='number') throw new Error('error')
      this._number=value
    }
}
})

If you want to hide the private _number you can wrap in a function

var box=(function() {
    var _number
    var box =Object.create({},{
    number: {    
        get: function() { return _number || 0; },
        set: function(value) {
          if(typeof value!='number') throw new Error('error')
          _number=value
        }
    }
    })
    return box
})()

box.number=3

More info:

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.