Can we set persistent default parameters which remain set until explicitly changed?

后端 未结 4 1125
你的背包
你的背包 2020-12-02 00:37

The below is a function fn where expected result is for a, b, c to defined at every call of fn, whether an o

相关标签:
4条回答
  • 2020-12-02 01:14

    Though code at OP uses single default parameter, until we locate or develop a procedure for using only single parameter, we can utilize setting two default parameters to achieve expected result.

    The first parameter defaults to a plain object, at second default parameter we pass parameter identifier from first parameter to Object.assign() following pattern at Question.

    We reference second parameter identifier of function fn to get the default parameters when called without parameters; when called with first parameter having properties set to properties of object passed at first parameter and default parameters, the former overwriting the latter at the resulting object.

    const fn = (__ = {}, opts = Object.assign({}, {a: 1, b: 2, c: 3}, __)) => 
                 console.log(opts);
    
    fn();
    
    fn({b: 7});
    
    fn({g: 9, x: 10});

    0 讨论(0)
  • 2020-12-02 01:20

    We can set fn as a variable which returns an arrow function expression. When called set a, b, c and rest parameters reference using spread element at new object, which is returned when the function is invoked.

    const fn = ((...opts) => ({a:1,b:2,c:3, ...opts.pop()}));
    
    let opts = fn();
    
    console.log(opts);
    
    opts = fn({b: 7});
    
    console.log(opts);
    
    opts = fn({g: 9, x: 10});
    
    console.log(opts);

    Using rest element, Object.assign(), spread element, Array.prototype.map(), setting element that is not an object as value of property reflecting index of element in array.

    const fn = ((...opts) => Object.assign({a:1,b:2,c:3}, ...opts.map((prop, index) =>
                 prop && typeof prop === "object" && !Array.isArray(prop) 
                 ? prop 
                 : {[index]:prop})) 
               );
    
    let opts = fn([2,3], ...[44, "a", {b:7}, {g:8, z: 9}, null, void 0]);
    
    console.log(opts);

    0 讨论(0)
  • 2020-12-02 01:22

    Maybe I misunderstood the question, but you seem to be looking for default initialisers for each separate property. For that, you have to use destructuring:

    const fn = ({a = 1, b = 2, c = 3} = {}) => console.log({a, b, c});
    

    If you want to keep arbitrary properties, not just those that you know of up front, you might be interested in the object rest/spread properties proposal that allows you to write

    const fn = ({a = 1, b = 2, c = 3, ...opts} = {}) => console.log({a, b, c, ...opts});
    

    Can an opts variable as the single object reference be achieved solely utilizing default parameters, without defining an object to reference outside of function parameters or within function body?

    No. Parameter declarations are only able to initialise variables with (parts of) the arguments, and possibly (as syntactic sugar) with default values when no or undefined argument (parts) are passed. They are not able to carry out unconditional computations and create variables inialised from the results - which is what you attempt to achieve here.

    You are supposed to use the function body for that.

    0 讨论(0)
  • 2020-12-02 01:23

    No

    The best that can be done is either your own answer or this:

    const fn = (default_parameters) => { 
      default_parameters = Object.assign({}, {a: 1, b: 2, c: 3},default_parameters);
      console.log('These are the parameters:');
      console.log(default_parameters);
    }
    
        fn();
    
        fn({b: 7});
    
        fn({g: 9, x: 10});

    The default parameter block is only executed if the value is not set, so your own answer is the best that is on offer ie use two parameters

    You can convince yourself of this by creating a code block that will fail if executed and testing that passing a parameter works (to show that the code block is not executed) and testing that not passing a parameter fails (showing that the code block is only executed when no parameter is passed).

    This should demonstrate clearly that any paramter passed will prevent the default parameter from being evaluated at all.

        const fn = (default_parameters = (default_parameters = Object.assign({}, {a: 1, b: 2, c: 3},default_parameters))) => { 
          
          console.log('These are the parameters:');
          console.log(default_parameters);
        }
    
            fn({b: 7});
            
            fn();
    
            fn({g: 9, x: 10});

    0 讨论(0)
提交回复
热议问题