How to handle nested default parameters with object destructuring?

前端 未结 3 1793
误落风尘
误落风尘 2021-01-04 13:47

I am trying to figure out if it is possible to handle multiple levels of default parameters with destructuring. Since it is not easy to explain with words, here is a step-by

3条回答
  •  温柔的废话
    2021-01-04 13:58

    I've got something that's a little simpler. It has drawbacks. But first, the goods:

    function doit( arg1 = 'one', hash = { prop1: 'two', prop2: 'three' }, { prop1, prop2 } = hash ) {
        console.log(`arg1`, arg1)
        console.log(`prop1`, prop1)
        console.log(`prop2`, prop2)
        console.log(`hash`, hash)
    }
    

    What does this accomplish?

    • provides names for all positional arguments, including the hash of named arguments
    • destructures all named arguments
    • provides a default value for every argument, whether positional or named

    How does it work?

    ES6 parameter defaults can refer to other parameters, like so:

    function math( x = 1, y = x ) { ... }
    // x = 1
    // y = 1
    

    So, even though the example function is designed to accept two arguments (arg1 and hash), the signature is formally declared with three arguments. The third argument is a kind of fictional or temporary argument that exists solely for the purpose of destructuring hash. It is the logical equivalent of this:

    function doit( arg1 = 'one', hash = { prop1: 'two', prop2: 'three' } ) {
        let { prop1, prop2 } = hash
        ...
    }
    

    The virtue of this pattern is that the signature is completely self-documenting. It's sadly very common in JS to see signatures declared like this:

    function terminateEmployee( employeeId, options ) {
        // what properties does `options` accept??
    }
    

    To answer that question, you need to search all downstream codepaths and collect every use of options. Sometimes that codepath is really long; if you're unlucky enough to be working in a microservice-based ecosystem, that codepath can span two or more additional codebases in other languages (true story).

    Yes, we can ask devs to write documentation, but YMMV on that score.

    So, this pattern allows the implementation to be self-documenting, without relying on extra documentation that devs would need to write and maintain.

    The downside is that the function looks like it accepts three arguments -- and it really does accept three. So, devs who are unaware of what's going on can be misled. And, if a caller passes three args, the third arg will override the second arg.

提交回复
热议问题