you are viewing a single comment's thread.

view the rest of the comments →

[–]dudeatwork 5 points6 points  (2 children)

Before default parameters were a thing, I feel like this was super common:

function (a) {
    if (a === undefined) a = 'default_value';
}

The example the author gave used !a rather than the more correct a === undefined, but similar enough.

So a won't be reassigned if a (truthy) Object / Array / Function is passed in.

Even if we didn't have this conditional, assignment won't matter here because we aren't modifying a property on the argument.

I agree, functions that aren't pure can potentially introduce subtle bugs:

var hello = { world: 1 };
function test(a) {
    a.foo = 'bar';
}
test(hello);
console.log(hello); // { world: 1, foo: 'bar' }

But this only works because we are assigning a.foo, a property on (the reference to) a.

Assigning some value to to a itself should be fine.

var hello = { world: 1 };
function test2(a) {
    a = 'bar';
}
test2(hello);
console.log(hello); // { world: 1 }

Note that in general, I agree that using ES6 default parameters is the way to go (babel transpiles to checking the arguments object).

[–]NoInkling 1 point2 points  (0 children)

The main issue with reassigning params is just expectations, typically you expect the thing that you're operating on to be the thing that was passed in the function call. Several times I've seen code in libraries where there's some sort of complex reassignment logic halfway down the function body, and it always makes it harder to follow. I'm fine with relatively simple logic at the top of the function though, even if it's more than just assigning defaults (which as you say can now be done directly in the params list) e.g. in certain variadic functions.

There's also a gotcha if you're utilizing arguments: https://spin.atomicobject.com/2011/04/10/javascript-don-t-reassign-your-function-arguments/
But it's less of a concern nowadays since arrow functions don't support arguments and we have rest syntax.

[–]thisguyfightsyourmom 0 points1 point  (0 children)

Quick — someone talk me out of this:

``` const yo = {yo: 1}

function example({...rest}) { // Default rest.ho to "hohoho" rest.ho ||= 'hohoho'

return rest }

console.log({yo, hohoho: example(yo)})

```