我们可以设置持久性默认参数,这些参数在显式更

时间:2022-01-31 00:57:42

The below is a function fn where expected result is for a, b, c to defined at every call of fn, whether an object parameter is passed or not. If object is passed which sets property, property should be set only for that object.

下面是函数fn,其中预期结果是a,b,c在每次调用fn时定义,是否传递了对象参数。如果传递了设置属性的对象,则应仅为该对象设置属性。

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

when called without parameters the result is

当没有参数调用时,结果是

fn() // {a: 1, b: 2, c: 3}

when called with parameter, for example {b:7}, the expected result is

当使用参数调用时,例如{b:7},预期结果为

fn({b:7}) // {a: 1, b: 7, c: 3}

however, the actual result is

但实际结果是

fn({b:7}) // {b: 7}

Was able to get expected result by defining an object outside of function and using Object.assign() within function body

能够通过在函数外部定义对象并在函数体内使用Object.assign()来获得预期结果

const settings = {a: 1, b: 2, c: 3};
const fn = opts => {opts = Object.assign({}, settings, opts); console.log(opts)}
fn({b: 7}) // {a: 1, b: 7, c: 3}
fn(); // {a: 1, b: 2, c: 3}
/*
  // does not log error; does not return expected result
  const fn = (opts = Object.assign({}, settings, opts)) => console.log(opts)
 
*/

Can the above result be achieved solely utilizing default parameters, without defining an object to reference outside of function parameters or within function body?

上述结果是否可以仅使用默认参数来实现,而无需在函数参数之外或函数体内定义要引用的对象?

4 个解决方案

#1


3  

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

如果你想保留任意属性,而不仅仅是那些你事先知道的属性,你可能会对允许你写的对象rest / spread属性提议感兴趣

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?

可以仅使用默认参数来实现opts变量作为单个对象引用,而无需在函数参数之外或函数体内定义要引用的对象吗?

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.

你应该使用函数体。

#2


2  

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});

#3


0  

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.

我们可以将fn设置为一个返回箭头函数表达式的变量。当调用set a,b,c和rest参数时,使用新对象的spread元素引用,该函数在调用函数时返回。

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.

使用rest元素,Object.assign(),spread元素,Array.prototype.map(),将不是对象的元素设置为反映数组中元素索引的属性值。

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);

#4


-1  

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.

虽然OP中的代码使用单个默认参数,但在我们找到或开发仅使用单个参数的过程之前,我们可以利用设置两个默认参数来实现预期结果。

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.

第一个参数默认为普通对象,在第二个默认参数,我们将参数标识符从第一个参数传递给在问题后面的模式下的Object.assign()。

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.

我们引用函数fn的第二个参数标识符来获取没有参数时调用的默认参数;当第一个参数调用属性设置为在第一个参数和默认参数传递的对象的属性时,前者在结果对象上覆盖后者。

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

fn();

fn({b: 7});

fn({g: 9, x: 10});

#1


3  

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

如果你想保留任意属性,而不仅仅是那些你事先知道的属性,你可能会对允许你写的对象rest / spread属性提议感兴趣

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?

可以仅使用默认参数来实现opts变量作为单个对象引用,而无需在函数参数之外或函数体内定义要引用的对象吗?

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.

你应该使用函数体。

#2


2  

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});

#3


0  

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.

我们可以将fn设置为一个返回箭头函数表达式的变量。当调用set a,b,c和rest参数时,使用新对象的spread元素引用,该函数在调用函数时返回。

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.

使用rest元素,Object.assign(),spread元素,Array.prototype.map(),将不是对象的元素设置为反映数组中元素索引的属性值。

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);

#4


-1  

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.

虽然OP中的代码使用单个默认参数,但在我们找到或开发仅使用单个参数的过程之前,我们可以利用设置两个默认参数来实现预期结果。

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.

第一个参数默认为普通对象,在第二个默认参数,我们将参数标识符从第一个参数传递给在问题后面的模式下的Object.assign()。

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.

我们引用函数fn的第二个参数标识符来获取没有参数时调用的默认参数;当第一个参数调用属性设置为在第一个参数和默认参数传递的对象的属性时,前者在结果对象上覆盖后者。

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

fn();

fn({b: 7});

fn({g: 9, x: 10});