简体   繁体   中英

Javascript class - how to make properties required and optional

I'm building a event tracking api and need to provide a JS class with a list of properties of which some of them will be required and some optional. Also, no new properties should be added.

Once the client instantiates and passes the object based on the class, I will be serializing the object and sending it as query string. I already have this part but not sure how to restrict the client from creating new properties.

How do I go about designing the class in JS?

There are a number of ways of doing the things you're wanting. Required/Optionals are pretty easy with utilities like underscorejs/jquery extend, along with some of underscore's utility methods (map, reduce,etc.).

To prevent an object from actually having additional properties though is a bit trickier. You could run an array of known required/optional properties as a check and do a delete on any property values that don't match your criteria.

Another option is to use something like seal. You read up more about this on mozilla's website here .

So I guess what I'd do is get the required properties working first by doing a sanity check against their existence. Your optionals could be provided and wrapped/unwrapped by using extend.

Finally (and maybe an even better route) would be to force the user to call getter/setter methods like setMyProperty( 'value' ) in order to populate any required/optional property value. This way, you aren't going to have to write a big hairy solution using the tools above.

JS is just funny like that. Neither solution is perfect, but they are both possible solutions. I'm sure there are others too. This is just a part of JS that can be a bit of a pain in the arsonal. Good luck.

>>> Edit <<<

This may not be perfect, but this is what I've done so far for the optional/required properties. I am obviously assuming they would just be passing in a set of properties in the constructor.

    var _Required = {
        requiredProperty1: null,
        requiredProperty2: null,
        requiredProperty3: null
    };

    var _Optionals = {
        optionalProperty1: null,
        optionalProperty2: null,
        optionalProperty3: null
    };

    var EventTrackerAPI = function( settings ) {
        var requiredProp, optionalProp;

        this.required = {};
        this.optional = {};

        for( requiredProp in _Required ) {
            if( !settings.hasOwnProperty( requiredProp ) ) {
                throw new Error( 'FAILED to create an instance of EventTrackerAPI - Required Property (' + requiredProp + ') Missing!' )
            }

            this.required[requiredProp] = settings[requiredProp];
        }

        for( optionalProp in _Optionals ) {
            if( settings.hasOwnProperty( optionalProp ) ) {
                this.optional[optionalProp] = settings.hasOwnProperty( optionalProp );
            } else {
                this.optional[optionalProp] = null;
            }
        }
    };

Anyways, I'd probably do something like the above. It isn't perfect yet (since I threw it together in about 10 minutes), but it should be a good start. I would also just not allow access to the private storage either.

When I was ready to actually extract the properties (like when you're ready to serialize), I'd do something similar as is being done in the constructor - just manually go through and grab the things you actually want - everything else would just be discarded this way. As a matter of fact, it may make sense to strip out the optional/required logic and make them methods on the object's prototype ( EventTrackerAPI.prototype.extractRequired = function( required ) {.... } for example...)

为什么不使用带有构造函数的类 - 那么你将拥有所需的属性

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM