Reassign JavaScript Function Parameters In Reverse Order, Or Lose Your Params


Every now and then I need to have a method support 2 or 3 arguments, providing a default value for one of them if only 2 are specified. My typical solution is to check the number of arguments passed to the function and reassign the named parameters as needed. I think this is a fairly typical solution in JavaScript. Except I spent about 30 minutes trying to track down a bug, just now, and it’s somewhat perplexing to me.

Can You Spot The Bug?

Here’s a sample of the code in question, that you can run from NodeJS. I’m using NodeJS 0.10.26 in this case.

There isn’t anything terribly special here. Check the number of arguments. If it’s 2, then re-assign the ‘a’ variable to a default, reassign ‘b’ to what ‘a’ originally was, and reassign ‘c’ to what ‘b’ originally was. Note that I’m doing this reassignment through the use of the arguments array, as well.

Can you guess what the output is, based on the code above?

NewImage

#WAT

Why are my parameters empty?

How I Thought Parameters Worked

I’ve always assumed method parameters worked the same way as variables. If I have 2 variables pointing at the same data, and I reassign one of them, then the other one is not reassigned.

This makes sense to me. This is how by-reference variables have always worked in my mind. And so, I’ve always expected function parameters to work the same. But apparently method parameters don’t work this way. Based on the above behavior, my currently confused understanding of this relationship says that the “a” parameter is not actually a variable in JavaScript. Rather, it’s some special construct that references the value of arguments[0]… not a by-ref variable that points to this value, but more like a by-val variable that *IS* the value of this memory location.

Given this by-val nature of the named parameter -> arguments[n] relationship, when my code above assigned “a” to an empty string it wiped out the “arguments[0]” value as well.

#WAT

Fixing The Bug: Reverse The Reassignment Order

In order to work around this, you have to reassign the parameters in reverse order.

And now the results are what I expected:

NewImage

By-Val Params

It turns out JavaScript does treat params and the arguments object as a by-val relationship. You change one, the other is also changed, unlike standard variables. From what I’ve read, this isn’t just NodeJS either – it’s the JavaScript spec.

Honestly, I had no idea that it was treating function parameters as by-val. After all these years with JavaScript, this language still surprises me.

Build A (local) Webcam With WebRTC In Less Than 20 Lines!