Reputation: 12549
I have a Javascript class (using John Resig's approach) that I create an instance of and pass an args
object, like so:
var myCucumber = new Cucumber({
size: 'small'
organic: true
})
Within the class itself, it references many properties on the args
object. However none of the properties are meant to be mandatory, so there may be some missing ones at times, which causes "property is undefined" errors.
To remedy this, I do the following:
args.size = args.size || null;
args.organic = args.organic || false;
args.colour = args.colour || null;
args.origin = args.origin || null;
It seems kind of annoying to have to do this for each property that may get used throughout the class.
Is there a clean way to assume that any property of args will be null
if it hasn't been passed in when an instance of the class was created?
Upvotes: 1
Views: 685
Reputation: 10719
You have a few ways of doing it, however I would not use the Resig method, as it has problems in ES5 Is John Resig's Javascript inheritance snippet deprecated?
1) (Resig) Create a constructor function and assign values to the all the properties that do not exist:
var Cucumber = Class.extend({
{
init: function(args){
this.size = null;
this.organic = false;
//etc
for (var key in args.keys()) {
this[key] = args[key];
}
},
}
2) second option use the Object.create with descriptors. This provides you the ability to create object properties with default values.
// Example where we create an object with a couple of sample properties.
// (Note that the second parameter maps keys to *property descriptors*.)
o = Object.create(Object.prototype, {
// foo is a regular 'value property'
size: { writable: true, configurable: true, value: null },
});
3) simliarly use Object.defineProperty
I prefer the two later ways, it as I believe it's clear and better to use the Object.create / Object.defineProperty, here is some additional info on the matter:
http://jaxenter.com/a-modern-approach-to-object-creation-in-javascript-107304.html
Understanding the difference between Object.create() and new SomeFunction()
Upvotes: 2
Reputation: 5451
I suggest addding a function to handle values in the expected way.
Example:
Cucumber.prototype._args = function(attr) {
return this.args[attr] || null;
}
// Then you may use it to access values as follows:
this._args('size');
Upvotes: 3
Reputation: 3105
You can check if any of object attribute has already been set just before you refer it, like @adeneo suggested.
If your object has a long list of attributes, you can use @aliasm2k's solution.
Or you can write an object constructor function and use it. For example
function ToothPaste(color = null, flavor = null, amount = null){
this.color = color;
this.flavor = flavor;
this.amount = amount;
}
var myTp = new ToothPaste('white');
alert(myTp.color);
alert(myTp.flavor);
alert(myTp.amount);
Upvotes: 0
Reputation:
Try something like this:
for (var key in args.keys()) {
args[key] = args[key] || null;
}
This is because every object has a keys()
function that returns an array of keys of that object.
Reference: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object
Upvotes: 1