Destructuring and Function Arguments

By  on  

The JavaScript language has benefitted from some really awesome new features over the past few years, including arrow functions, the spread operator, and default function argument values.  Even if your browser doesn't yet support proposed JavaScript API syntax additions, you can use a tool like Babel in your Node.js app to take advantage of them today.

One of my favorite new(ish) JavaScript features is object destructuring.  If you aren't familiar with JavaScript destructuring, it basically provides a shorter syntax for extracting an object key's value without the dot notation mess:

// A sample object
const myObject = { x: 1, y: 2 };

// Destructuring
const { x, y } = myObject;
// x is 1, y is 2

The basic syntax for destructuring is fairly simple but using destructuring with function arguments can be a bit more difficult when those argument values should have default values.  The following is a function with arguments having default values:

function myFunction(text = "", line = 0, truncate = 100) {

    // With default values, we can avoid a bunch of:
    text = text || "";
    line = line || 0;
    truncate = truncate || 100;
}

Regardless of language, if a function takes more than ~3 parameters, it's probably best to pass in an object name options or config that contains possible key/values; the equivalent would look like:

function myFunction(config) {

}

// Usage
myFunction({
    text: "Some value",
    line: 0,
    truncate: 100
})

What if you want to use destructuring in JavaScript function arguments though?  The following function signature would become:

function myFunction({ text, line, truncate }) {

}

If you want to define defaults in the function configuration, you'd use the following:

function myFunction({ 
  text = "", 
  line = 0, 
  truncate = 100 
} = {}) {

 // Even if the passed in object is missing a given key, the default is used!
}

Setting a default with = { } is important; with no default the following example would error:

TypeError: Cannot destructure property `key` of 'undefined' or 'null'

Destructuring is an awesome language feature but can lead to confusion and even errors.  Hopefully the basics provided in this guide can help you to navigate using JavaScript destructuring with functions!

Recent Features

  • By
    JavaScript Promise API

    While synchronous code is easier to follow and debug, async is generally better for performance and flexibility. Why "hold up the show" when you can trigger numerous requests at once and then handle them when each is ready?  Promises are becoming a big part of the JavaScript world...

  • By
    5 HTML5 APIs You Didn’t Know Existed

    When you say or read "HTML5", you half expect exotic dancers and unicorns to walk into the room to the tune of "I'm Sexy and I Know It."  Can you blame us though?  We watched the fundamental APIs stagnate for so long that a basic feature...

Incredible Demos

  • By
    Using MooTools to Instruct Google Analytics to Track Outbound Links

    Google Analytics provides a wealth of information about who's coming to your website. One of the most important statistics the service provides is the referrer statistic -- you've gotta know who's sending people to your website, right? What about where you send others though?

  • By
    Chris Coyier’s Favorite CodePen Demos II

    Hey everyone! Before we get started, I just want to say it's damn hard to pick this few favorites on CodePen. Not because, as a co-founder of CodePen, I feel like a dad picking which kid he likes best (RUDE). But because there is just so...

Discussion

  1. I think you’ll get the expected behavior if you provide individual defaults for each option as well as a fallback empty-object default for the options arg:

    function myFunction({ text = "", line = 0, truncate = 100 } = {}) {...}

    Otherwise if you pass eg an options object with just one option set, the other defaults won’t kick in

    • Excellent point! I’ve updated the post to fix my oversight. Thank you!

  2. How can I use this in class constructor? any views?

  3. Sagar

    Hi David,

    You’re article on destructor is simple but in real application we have to deal with nested object. I requested you can you write blog for nested objects.

    Thanks

  4. Nils Devine

    For anyone trying to do this with TypeScript, here’s the tricky bit (RequestParams is an interface defined elsewhere).

            {
                offset = 0,
                limit = 0,
                pageSize = 25,
                filter,
                sort,
            }: RequestParams = {} as RequestParams
    
  5. Damon

    I am curious.. if (using the code from the article) I want to allow a single parameter passed as a string to represent the string with the line/truncate params as their default.. is there a way to do that within the function params? or do i have to rebuild the params separately?

  6. Andrew

    I see benefits with deconstructing with typing (via TypeScript) or having default values, but using it with just the deconstruction can lead to a lot of confusion in calling that function ie, the object param must have the necessary keys, in fact any object with those keys could be passed into the function, and if a user doesn’t know the function signature it gets messy and hard to follow.

Wrap your code in <pre class="{language}"></pre> tags, link to a GitHub gist, JSFiddle fiddle, or CodePen pen to embed!