How does this particular scenario of default params and destructuring work?
Asked Answered
O

5

9

I was trying some things today and came across a behaviour I would like to understand.

var b = ({a = 1, b = 1, c = 1}) => a + b + c;

b(); // throws error.

But if it is defined like this

var b = ({a = 1, b = 1, c = 1} = 0) => a + b + c;

b() // returns 3
b([]) // returns 3

Shouldn’t this be an error? Did zero somehow become an object here? Is it somehow equivalent to the following?

var b = ({a = 1, b = 1, c = 1} = {}) => a + b + c; // this is possible I guess.

My question is not how regular destrcuturing and default params work, but only how this particular scenario is being evaluated.

Can some one explain this to me?

Octarchy answered 3/5, 2018 at 12:7 Comment(0)
D
5
({a = 1, b = 1, c = 1} = something) => {}

just means that something must be an object or can be converted to one, i.e. it can’t be null or undefined.1

So, in the case of 0, it proceeds to grab the a, b and c properties of 0, i.e. (0).a, (0).b, (0).c, all of which are undefined, hence all of them default to 1, their provided default value.

0 can of course be coerced to a Number object. That’s why you can do (0).toString() or {toString} = 0. That’s exactly what happens here.

It’s generally not equivalent to using {} as a default, since that would use an empty object’s properties (both own properties and the ones on the prototype chain), not the number’s properties.


1: The most reduced form of this “structural verification” is ({} = something). For destructuring onto arrays, it is ([] = something) and it means that the something must also be iterable. Those empty destructuring assignments, by the way, don’t create any variables, they just do the structure check.

Dendritic answered 3/5, 2018 at 12:25 Comment(5)
so it doesn't matter whatever i pass as default as long as they can be coerced into an object it will work?Octarchy
Anything except null or undefined will work. For example: var f = ({toFixed=null} = 0)=>typeof toFixed;f(); will print "function" instead of null.Theolatheologian
@ShyamBabu Yes, calling that function without arguments, or with undefined or null will work, but you should also ask yourself, whether 0 is a sensible default.Dendritic
0 is not sensible i agree, just curious on this behaviour. So in the case of array destructuring then is this also the behaviour?Coercion into array?Octarchy
@ShyamBabu In the case of array destructuring, the something must also be iterable. Arrays, maps, sets, arguments, HTMLCollections, etc. will all work, but other, non-iterable values will fail. Other than that, it works the same way.Dendritic
S
1
var b = ({a=1,b=1,c=1})=>a+b+c
b() //throws error.

It expect to have some params passed in as input instead you are calling b() without passing anything.

var b = ({a=1,b=1,c=1} = 0)=>a+b+c 
b() //return 3

It works because you have assigned it an initial value {a=1,b=1,c=1} = 0 which is 0 and it is creating the 3 vars you are using a+b+c with default value = 1

Stoddard answered 3/5, 2018 at 12:19 Comment(0)
P
0

Destructing works with both arrays and objects. From what I found out in Object patterns restructuring

The object pattern coerces destructuring sources to objects before accessing properties

For eg.

const {length : len} = 'abc'; // len = 3
const {toString: s} = 123; // s = Number.prototype.toString

In your case:

b([]) // return 3 as it arrays destructing
b({a=1,b=2,c=3} =0) // works because of object coercion

Please check this link for more information.

Padraic answered 3/5, 2018 at 12:19 Comment(0)
E
0

Reason: In JavaScript, the compiler does auto typecasting, so 0 is treated as 'Object(0)' because the function b expects the Objects as an input.

More Details: The function b is taking input as an Object with defaults of a,b,c by Object destructing.

so the callers of b has to pass an Object, if nothing is passed it throws an error. When something is passed to b, it tries to extract a,b,c values from the Object passed. If something is passed it takes those values and if nothing is passed defaults to values given in definition

Example, If you pass something like this b({a : 10, b: 20}) it defaults c values to 1 and Prints 31

For b({a : 10, d: 20}), b and c turns to default and returns 12.

Hope this helps to understand.

Existential answered 3/5, 2018 at 12:22 Comment(0)
D
-1

It takes the prototype of the primitive value and uses it as the destructuring value.

var b = ({ a = 1, b = 1, c = 1, toFixed } = 0) => toFixed.bind(a + b + c)(2);

console.log(b());
Doornail answered 3/5, 2018 at 12:16 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.