TLDR; All arguments are passed by value in JavaScript, however, when dealing with non-primitive datatypes like objects and arrays a variable is created that points to the location of the object memory that is then is passed into the function. This means that changes to the variable inside the function will affect the original object's values. Once the argument is reassigned (e.g.
arg = {}
) the variable now has the location of the new object in it so the original variable is no longer changed when the value changes.By Reference vs. By Value
Let's start be defining exactly what by passing a variable reference and by value actually means.By Reference
If a parameter is being passed into a function by reference it means that only a reference to the variable is being passed into the function is passed as the argument. The variable in the function and the variable that is passed into the function are actually pointing to the same location in memory. Put simply, if the value is modified inside the function the original value is also changed.By Value
If a value is being passed into a function by value it means that a copy of the variable is being passed into the function. The variable in the function and the variable that is passed into the function are two separate variables. Put simply, if the value is modified inside a function the original value will remain unchanged.By The Book
According to MDN:The parameters of a function call are the function's arguments. Arguments are passed to functions by value. If the function changes the value of an argument, this change is not reflected globally or in the calling function. However, object references are values, too, and they are special: if the function changes the referred object's properties, that change is visible outside the function.
Huh?
Let me try to describe this with pictures. First let's create a variable that is a simple object literal:var obj = { foo : 'foo' };
When we do this the variable obj is really just a reference to a location in memory that holds the actual object:
If a function is invoked and obj is passed into the function as an argument that reference is copied and passed into the function. In other words, the reference is being passed by value:
doSomething( obj );
This is where things start to get interesting. The pointer to the object is passed into the function call by value. In other words, a copy of the pointer is created and passed into the function call. We now have two variables that point to the same object:
At this point if the argument is modified inside the function call the changes will be reflected on the original varialbe outside of the function call. However if the argument is reassigned inside the function the reference will no longer point to the original object and changes inside the function will no longer affect the variable outside the function call:
function doSomething( obj ){
obj = { baz : 'baz' }; //reassigns the pointer
}
After reassignment our objects in memory look like this: