Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Destructuring objects as function parameters deep extend

Is it possible to "deep extend" objects when using destructuring to set default properties of an object passed into a function?

Example:

function foo({
  foo = 'foo',
  bar = 'bar',
  baz = {
    propA: 'propA',
    propB: 'propB'
  }
} = {}) {
  console.log(foo);
  console.log(bar);
  console.log(baz);
}

foo({
  foo: 'changed',
  baz: {
    propA: 'changed'
  }
});

This outputs: (baz is overwrote)

changed
bar
{
  "propA": "changed"
}

Is there syntax which will extend the baz object, to give output:

changed
bar
{
  "propA": "changed",
  "propB": "propB"
}
like image 405
Fergal Avatar asked Dec 05 '16 11:12

Fergal


People also ask

Can you Destructure a function?

To destructure an object inside a function's parameters we place a set of curly braces inside the parentheses of the function. Inside the curly braces, we place the properties of the object which we wish to pick out. Below is an example using an arrow function.

Can we Destructure function in JavaScript?

The destructuring is also possible for JavaScript Arrays. By default, the object key name becomes the variable that holds the respective value. So no extra code is required to create another variable for value assignment.

How do you Destructure an object inside an array?

Destructuring in Arrays. To destructure an array in JavaScript, we use the square brackets [] to store the variable name which will be assigned to the name of the array storing the element. const [var1, var2, ...]

How do you Destructure an object using the spread Operator?

Similar to arrays, destructuring an object for specific properties is as easy as wrapping the variables inside of curly brackets to denote we are doing object destructuring. You then just put the object you want to get the values from on the right side of the equals sign.


1 Answers

There is no native-way to do what you ask, but you can write your own function decorator, of course it is a verbose approach...

Note: In order to perform a deep merge you should use some of the existing solution developed by the community, both Object.assign and Object Spread Operator perform a shallow copy of the source, even, writing your own deepmerge function could be error-prone. I suggest you to use lodash#merge that is commonly accepted as one of the solid solutions to the problem.

var {
  // https://lodash.com/docs/#merge
  merge
} = require('lodash');

function defaultsArgDecorator(defaults, target) {

  return function(args) {
    
    return target(
      merge(Object.create(defaults), args)
    )
  }
}


function _foo(args) { console.log({args}); }
var foo = defaultsArgDecorator({
  foo: 'foo',
  bar: 'bar',
  baz: {
    propA: 'propA',
    propB: 'propB'
  }
}, _foo);

foo({bar: "ciao bello", baz: {propA: "HELLO"}})
like image 88
Hitmands Avatar answered Sep 20 '22 13:09

Hitmands