Destruction of objects in the form of functional parameters

Is it possible to use "deep expansion" objects when using destructuring to set the default properties of the object passed to the 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' } }); 

These outputs: (base overwritten)

 changed bar { "propA": "changed" } 

Is there any syntax that extends the baz object to produce the result:

 changed bar { "propA": "changed", "propB": "propB" } 
+6
source share
4 answers

There is no own way to do what you ask, but you can write your own function decorator , of course, this is a detailed approach ...

Note. To perform deep merging , you must use some of the existing solutions developed by the community, and Object.assign and Object Spread Operator perform an incomplete copy of the source, even writing your own depth function can be error prone. I suggest you use lodash#merge , which is considered the best solution.

 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"}}) 
+5
source

Since restructuring the parameters allows you to use the previous parameters in the settings of other default parameters, you can create a property that does not go out of the original parameters, for example __baz , and set the default values ​​using baz . In the method, you will use __baz instead of baz .

Note: this is a hack, and if the object contains a property name __baz , it will override the default value with unexpected results. However, you can call the default property something like dontUse__baz , which has a very low chance of being used.

Default properties using Object#assign :

 function foo({ foo = 'foo', bar = 'bar', baz, __baz = Object.assign({ "propA": "changed", "propB": "propB" }, baz) } = {}) { console.log(foo); console.log(bar); console.log(__baz); } foo({ foo: 'changed', baz: { propA: 'changed' } }); 

Default properties using object distribution (babel plugin required - see link ):

 function foo({ foo = 'foo', bar = 'bar', baz, __baz = { "propA": "changed", "propB": "propB", ...baz } } = {}) { console.log(foo); console.log(bar); console.log(__baz); } foo({ foo: 'changed', baz: { propA: 'changed' } }); 
+4
source

You can also perform nested destructuring. You destroy the base, but also destroy propA and propB .

If you need your entire object and you do not want to "rebuild" it, this is not for you, but it performs one task of setting default values ​​for undefined properties nested in the object.

I left baz as a separate descriptive value in addition to its properties as an example of a sometimes convenient template, but you will most likely want to remove it, as it suffers from the same problem of losing default properties.

 function foo({ foo = 'foo', bar = 'bar', baz, // likely extraneous and confusing, here for example baz: { propA = 'propA', propB = 'propB' } } = {}) { console.log(foo); console.log(bar); console.log(propA, propB); console.log(baz); console.log(Object.assign(baz, {propA, propB})); } foo({ foo: 'changed', baz: { propA: 'changed' } }); 
0
source

Yes, it is possible!

Solution 1:

 function foo({ foo = 'foo', bar = 'bar', baz: { propA = 'propA', propB = 'propB' } = {} }) { console.log(foo) console.log(bar) console.log({propA, propB}) // Because `bar` is renamed to `{propA, propB}`. Hence, no local variable named `baz` } 

Solution 2 (workaround):

 function foo({ foo = 'foo', bar = 'bar', baz = {} }) { // ... const baz2 = Object.assign({}, {propA: 'propA', propB: 'propB'} = {}) console.log(baz2) // Yeah, not really a solution } 

You can even do this:

 const func = ([{foo, bar: {a, b: BB, c: CC = 'c'} = {}} = {}], ...{0: rest0 = 0, 1: rest1 = '1'}) => { /* do stuffs */ } 

The above code is a complex example, I will use simpler examples to explain:

Example 1:

 const f1 = ({x: varx}) => console.log(varx) 

When you call f1(obj) , obj.x will be assigned to varx in the f1 area

Example 2:

 const f2 = ({xy: {x, y}}) => console.log({x, y}) 

Like f1 , but with {x, y} instead of varx , obj.xy will be assigned {x, y} , so x = obj.xy.x and y = obj.xy.y

Example 3: Now add default options to create

 const f3 = ({xy: {x, y} = {}}) => { /* do stuffs */ } 

Now you still need to pass obj as an object, but you no longer need to provide obj.xy If obj.xy is undefined , x and y are undefined s

Example 4. Now let x and y have default values

 const f4 = ({xy: {x = 'XXX', y = 'YYY'} = {}}) => { /* do stuffs */ } 

If obj.xy you passed, it is undefined , {x, y} will be set to {x: undefined, y: undefined} , but since x and y also have default values, x will be 'XXX' and y will be 'YYY'

Example 4: "FORM OF ULTIMATE LIFE"

 const f5 = ({xy: {x = 'XXX', y = 'YYY'} = {}} = {}) => { /* do stuffs */ } 

I think I no longer need to explain this: D

-3
source

Source: https://habr.com/ru/post/1012895/


All Articles