My two cents.... It's irrelevant whether JavaScript passes parameters by reference or value. What really matters is assignment vs. mutation.
I wrote a longer, more detailed explanation in this link.
When you pass anything (whether that be an object or a primitive), all JavaScript does is assign a new variable while inside the function... just like using the equal sign (=).
How that parameter behaves inside the function is exactly the same as it would behave if you just assigned a new variable using the equal sign... Take these simple examples.
var myString = 'Test string 1'; // Assignment - A link to the same place as myString var sameString = myString; // If I change sameString, it will not modify myString, // it just re-assigns it to a whole new string sameString = 'New string'; console.log(myString); // Logs 'Test string 1'; console.log(sameString); // Logs 'New string';
If I were to pass myString as a parameter to a function, it behaves as if I simply assigned it to a new variable. Now, let's do the same thing, but with a function instead of a simple assignment
function myFunc(sameString) { // Reassignment... Again, it will not modify myString sameString = 'New string'; } var myString = 'Test string 1'; // This behaves the same as if we said sameString = myString myFunc(myString); console.log(myString); // Again, logs 'Test string 1';
The only reason that you can modify objects when you pass them to a function is because you are not reassigning... Instead, objects can be changed or mutated.... Again, it works the same way.
var myObject = { name: 'Joe'; } // Assignment - We simply link to the same object var sameObject = myObject; // This time, we can mutate it. So a change to myObject affects sameObject and visa versa myObject.name = 'Jack'; console.log(sameObject.name); // Logs 'Jack' sameObject.name = 'Jill'; console.log(myObject.name); // Logs 'Jill' // If we re-assign it, the link is lost sameObject = { name: 'Howard' }; console.log(myObject.name); // Logs 'Jill'
If I were to pass myObject as a parameter to a function, it behaves as if I simply assigned it to a new variable. Again, the same thing with the exact same behavior but with a function.
function myFunc(sameObject) { // We mutate the object, so the myObject gets the change too... just like before. sameObject.name = 'Jill'; // But, if we re-assign it, the link is lost sameObject = { name: 'Howard' }; } var myObject = { name: 'Joe' }; // This behaves the same as if we said sameObject = myObject; myFunc(myObject); console.log(myObject.name); // Logs 'Jill'
Every time you pass a variable to a function, you are "assigning" to whatever the name of the parameter is, just like if you used the equal = sign.
Always remember that the equals sign = means assignment. And passing a parameter to a function also means assignment. They are the same and the two variables are connected in exactly the same way.
The only time that modifying a variable affects a different variable is when the underlying object is mutated.
There is no point in making a distinction between objects and primitives, because it works the same exact way as if you didn't have a function and just used the equal sign to assign to a new variable.