Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save stonehippo/a5f839fb8ea93098b9af508cc8b34df2 to your computer and use it in GitHub Desktop.
Save stonehippo/a5f839fb8ea93098b9af508cc8b34df2 to your computer and use it in GitHub Desktop.
A quick exploration of using object destructuring to make better function parameters in ES6+
// A quick tutorial on object destructuring and Javascript functions
/*
note: I'm using var here because I'm going to refactor the example
function several times. You should not do this with real code!
*/
// To start, we'll create a simple function to make a rect tangle
var makeRect = function (height, width) {
return {height: height, width: width}
}
// > makeRect(10, 10) -> {height: 10, width: 10} / yay!
// > makeRect(10) -> {height: 10, width: undefined} / hmmm
// > makeRect() -> {height: undefined, width: undefined} / oh no
// Let's try to make this a little better by adding some defaults
var makeRect = function (height = 10, width = 10) {
return {height: height, width: width}
}
// > makeRect(10, 10) -> {height: 10, width: 10} / yay!
// > makeRect(10) -> {height: 10, width: 10} / better!
// > makeRect() -> {height: 10, width: 10} / ok!
// We can make it a little more compact, too, since the parameters match the output field names
var makeRect = function (height = 10, width = 10) {
return {height, width}
}
// or even more compact with an arrow function!
var makeRect = (height = 10, width = 10) => ({height, width})
// > makeRect(10, 10) -> {height: 10, width: 10} / still good
// > makeRect(10) -> {height: 10, width: 10} / still good
// > makeRect() -> {height: 10, width: 10} / still good
// But what if we want to be specific a width without specifying as height?
// It's time to get some named parameters via object destructuring!
var makeRect = ({height = 10, width = 10}) => ({height, width})
// > makeRect({height: 10, width: 10}) -> {height: 10, width: 10} / cool
// > makeRect({width: 10, height: 10}) -> {height: 10, width: 10} / also cool
// > makeRect({height: 100}) -> {height: 100, width: 10} / copacetic
// > makeRect({width: 100}) -> {height: 10, width: 100} / YES
// > makeRect({}) -> {height: 10, width: 10} / awesome
// > makeRect({boogie: "spoiler!"}) -> {height: 10, width: 10} / phew
// > makeRect() -> Uncaught TypeError: Cannot read property 'height' of undefined / oh crap
// To fix the empty case, we need to provide one more default
var makeRect = ({height = 10, width = 10} = {}) => ({height, width})
// > makeRect({height: 10, width: 10}) -> {height: 10, width: 10} / check
// > makeRect({width: 10, height: 10}) -> {height: 10, width: 10} / check
// > makeRect({height: 100}) -> {height: 100, width: 10} / check
// > makeRect({width: 100}) -> {height: 10, width: 100} / check
// > makeRect({}) -> {height: 10, width: 10} / check
// > makeRect({boogie: "spoiler!"}) -> {height: 10, width: 10} / check
// > makeRect() -> {height: 10, width: 10} / nailed it!
// Our new object is a little pudgy. Maybe we can shrink it down?
var makeRect = ({height = 10, width = 10} = {}) => ({h: height, w: width})
// > makeRect({height: 10, width: 10}) -> {h: 10, w: 10} / check
// > makeRect({width: 10, height: 10}) -> {h: 10, w: 10} / check
// > makeRect({height: 100}) -> {h: 100, w: 10} / check
// > makeRect({width: 100}) -> {h: 10, w: 100} / check
// > makeRect({}) -> {h: 10, w: 10} / check
// > makeRect({boogie: "spoiler!"}) -> {h: 10, w: 10} / check
// > makeRect() -> {h: 10, w: 10} / check
// But what about if we want maintain our sweet destructuring goodness on the return?
// We can, by renaming the parameters!
var makeRect = ({height: h = 10, width: w = 10} = {}) => ({h, w})
// won't bore with the output, it's the same as before!
// Lastly, what if we want to do something with some other parameters?
// For now, we'll just assume we want to shove them into our new object, because whatever
var makeRect = ({height: h = 10, width: w = 10, ...options} = {}) => ({h, w, options})
// All the cases above work, but check these out:
// > makeRect({height: 1000, boogie: true}) -> {h: 10000, w: 10, { boogie: true}} / check
// > makeRect({height: 1, width: 100, boogie: true}) -> {h: 1, w: 100, { boogie: true}} / check
// > makeRect({boogie: true}) -> {h: 10, w: 10, { boogie: true}} / check
// We can also spread the options out, if that's what we want
var makeRect = ({height: h = 10, width: w = 10, ...options} = {}) => ({h, w, ...options})
// All the cases above work, but check these out:
// > makeRect({height: 1000, boogie: true, jive: 1}) -> {h: 10000, w: 10, boogie: true, jive: 1} / check
// > makeRect({height: 1, width: 100, boogie: true}) -> {h: 1, w: 100, boogie: true} / check
// > makeRect({boogie: true}) -> {h: 10, w: 10, boogie: true} / check
// Ok, that's it. Have fun!
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment