A colleague of mine asked if a JavaScript method can update its input arguments. The answer is, sometimes.

If you're passing in simple value, such as a string it number, then that argument is passed by value and the underlying value is not updated.

Let's start with a function:

view plain print about
1function foo(myarg) {
2 myarg = 'bar'
3}

The foo function accepts an argument, changes its value, and returns nothing.

Now let's create a variable, call the function with the variable, and output the variable:

view plain print about
1let myVal = 'goo';
2foo(myVal);
3console.log(myVal) // should output goo value didn't change

You'll see that the value has not changed. This is called "Pass by Value" meaning the value of the variable is passed in; but a copy of the value is made for the internal variable, leaving the external variable untouched.

However, when we use complex objects, such as arrays or strings, these are passed by reference and we can modify them:

Take this function:

view plain print about
1function fooTwo(myarg) {
2 myarg.arg = 'bar'
3}

fooTwo accepts an object argument, and changes a property on it. There is no return.

Call the function with an object and output the results:

view plain print about
1let myVal2 = { arg: 'goo'};
2fooTwo(myVal2);
3console.log(myVal2); // should be bar value didn't change

The object is modified. This is often called Pass by Reference. The way objects are stored in memory is that the actual variable is a reference pointing to another memory space where the complex object exists. When we call the function, a copy of the reference is made, but it still points to the same underlying object. As such, changes to the object inside the function will also change the object outside of the function.

If at all possible, I like to implement pure functions that do not change the inputs, but instead return a copy of the modified object. Overall, that makes your code easier to debug because there are fewer side effects.

Play with the code here