43

Use destructuring in function parameters

Did you know that you can use destructuring in function parameters?

I am sure many of you are already familiar with the ES6 Destructuring Assignment. Did you know that you can also use it in function parameters?

var sayHello = function({ name, surname }) {
  console.log(`Hello ${name} ${surname}! How are you?`);
};

sayHello({ name: 'John', surname: 'Smith' })
// -> Hello John Smith! How are you?

This is great for functions which accept an options object. For this use case, you can also add default parameters to fill in whatever values the caller leaves out, or if the caller forgets to pass one at all:

var sayHello2 = function({ name = "Anony", surname = "Moose" } = {}) {
  console.log(`Hello ${name} ${surname}! How are you?`);
};

The = {} says that the default object to be destructured for this parameter is {}, in case the caller forgets to pass the parameter, or passes one of the wrong type (more on this below).

sayHello2()
// -> Hello Anony Moose! How are you?
sayHello2({ name: "Bull" })
// -> Hello Bull Moose! How are you?
Argument Handling

With plain destructuring assignment, if the the input parameter can’t be matched with the function’s specified object arguments, all the unmatched arguments are undefined, so you need to add code that handles this properly:

var sayHelloTimes = function({ name, surname }, times) {
  console.log(`Hello ${name} ${surname}! I've seen you ${times} times before.`);
}

sayHelloTimes({ name: "Pam" }, 5678)
// -> Hello Pam undefined! I've seen you 5678 times before.
sayHelloTimes(5678)
// -> Hello undefined undefined! I've seen you undefined times before.

Worse, if the parameter to be destructured is missing, an exception is thrown, probably bringing your app to a screeching halt:

sayHelloTimes()
// -> Uncaught TypeError: Cannot match against 'undefined' or 'null'...

It’s conceptually similar to accessing a property of an undefined object, just with a different exception type.

Destructuring assignment with default parameters hides all the above to a certain extent:

var sayHelloTimes2 = function({ name = "Anony", surname = "Moose" } = {}, times) {
  console.log(`Hello ${name} ${surname}! I've seen you ${times} times before.`);
};

sayHelloTimes2({ name: "Pam" }, 5678)
// -> Hello Pam Moose! I've seen you 5678 times before.
sayHelloTimes2(5678)
// -> Hello Anony Moose! I've seen you undefined times before.
sayHelloTimes2()
// -> Hello Anony Moose! I've seen you undefined times before.

As for = {}, it covers the case of a missing object, for which individual property defaults won’t help at all:

var sayHelloTimes2a = function({ name = "Anony", surname = "Moose" }, times) {
  console.log(`Hello ${name} ${surname}! I've seen you ${times} times before.`);
};

sayHelloTimes2a({ name: "Pam" }, 5678)
// -> Hello Pam Moose! I've seen you 5678 times before.
sayHelloTimes2a(5678)
// -> Hello Anony Moose! I've seen you undefined times before.
sayHelloTimes2a()
// -> Uncaught TypeError: Cannot match against 'undefined' or 'null'.
Availability

Note that destructuring assignment may not yet be available by default, in the version of Node.js or browser that you’re using. For Node.js, you can try using the --harmony-destructuring flag on startup to activate this feature.