1

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?

shrewdbeans
  • 11,971
  • 23
  • 69
  • 115
  • 4
    Wherever you're using it, couldn't you just check for `undefined` instead, or both, or here's a crazy idea, just check for anything falsy ? – adeneo Jun 20 '15 at 16:16
  • If you do want to use these properties, just initialize them with some initial values (or even null) in its constructor. – TaoPR Jun 20 '15 at 16:21

4 Answers4

3

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');
Dimitris Zorbas
  • 5,187
  • 3
  • 27
  • 33
2

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()

Community
  • 1
  • 1
Dory Zidon
  • 10,497
  • 2
  • 25
  • 39
1

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

0

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);
Alp
  • 3,027
  • 1
  • 13
  • 28