Code Tips #3: Remove argument-order dependency and provide defaults

Argument order in function signature is a common source of bugs and frustration. Imagine you have the following Vehicle class, its constructor accepts values to instantiate an object. Passing the values in the wrong order can easily lead to bugs that are not so easy to catch.

class Vehicle {
  constructor(speed, weight, power, color, brand){
    this.speed = speed;
    this.weight = weight;
    this.power = power;
    this.color = color;
    this.brand = brand;
  }
}

Obviously we can avoid the order depedency by passing a hash object to the function.

class Vehicle {
  constructor(args = {}){
    Object.keys(args)
      .forEach(argument => this[argument] = args[argument]);
  }
}

There is a problem though, what if we want our constructor to have some default values in case these are not provided? In the first example, we would write our class like that:

class Vehicle {
  constructor(speed = 100, weight = 1500, power = 111, color = "red", brand = "Kia"){
    this.speed = speed;
    this.weight = weight;
    this.power = power;
    this.color = color;
    this.brand = brand;
  }
}

To provide defaults in case we use hash object as a signle parameter, we can create a defaults property that returns our defaults, and merge the passed args object with our defaults in the constructor. The defaults property acts also as a form of documentation for the properties our class expects.

class Vehicle {
  constructor(args = {}){
    args = { ...this.defaults, ...args };
    Object.keys(args)
      .forEach(argument => this[argument] = args[argument]);
  }

  get defaults(){
    return {
      speed: 100,
      power: 1000
    }
  }
}

Leave a Reply

Your email address will not be published. Required fields are marked *