Wednesday 15 November 2017

Javascript Default Parameters

As default parameters, Object.assign and destructuring assignment have made it into the language the way to work with optional parameters and default values has changed. I've been writing some examples to get used to the current options and I'll be explaining it here:

Let's say we have a function (or method, but not a constructor) expecting a few parameters. The old-school way to deal with default values was this:

function formatString(st, pre, post){
 pre = pre || "[";
 post = post || "]";
 return pre + st + post;
}

That was a nice Javascript idiom, but since default parameters were added to the language we can do just this:

function formatString(st, pre="[", post= "]"){
 return pre + st + post;
}

That's nice for functions expecting just a few parameters, but if we have many values to pass, we will be joining them in an "options object". This is not just a consequence of javascript missing named arguments, even if we had them (like in C#) having a method signature with a large list of parameters is rather painful and an "options object" is a much better option. For this case we can use destructuring assignment like this:

function formatString(st, {
   pre = "[",
   post = "]"
  } = {}){
 return pre + st + post;
}

console.log(formatString("hi"));
console.log(formatString("hi", {pre: "X"}));
console.log(formatString("hi", {pre: "X", post: "X"}));

If we have a constructor function where we are receiving several values to be assigned to the instance being created, we can do like in the first 2 examples above:

class Formatter{
 constructor(pre, post){
  this.pre = pre || "[";
  this.post = post || "]";
 }

}

class Formatter{
 constructor(pre="[", post= "]"){
  this.pre = pre;
  this.post = post;
 }
} 

But if we are passing an options object which properties we will be assigning to this, we'll have to use Object.assign:

class Formatter{
 constructor(options){
  let defaults = {
   pre: "[",
   post: "]"
  };
  Object.assign(this, defaults, options);
 }
 
 formatString(st){
  return this.pre + st + this.post;
 }
}
 
let formatter = new Formatter();
console.log(formatter.formatString("hi"));

formatter = new Formatter({pre: "X"});
console.log(formatter.formatString("hi"));

formatter = new Formatter({pre: "X", post: "X"});

Given that I mention Object.assign, ES Next features a pretty nice way to join several objects into a new one by means of the spread in object literals

var obj1 = { foo: 'bar', x: 42 };
var obj2 = { foo: 'baz', y: 13 };
var clonedObj = { ...obj1 };

// Object { foo: "bar", x: 42 }

var mergedObj = { ...obj1, ...obj2 };
// Object { foo: "baz", x: 42, y: 13 }

No comments:

Post a Comment