In JavaScript, a variable may store two types of data: primitive and reference. When you assign a variable a value, the JavaScript engine must determine whether the value is a primitive or a reference value. If the variable stores a primitive value, any change to this value does not change the original variable’s value but only the actual value stored in the variable you are working with.

See the Pen thecodelog.com - JS By Val By Ref 1 by Deano (@deangilewicz) on CodePen.

When you assign a variable an object (object, array, function) and manipulate the value, you are working on the reference to that object so all references are changed.

See the Pen thecodelog.com - JS By Val By Ref 2 by Deano (@deangilewicz) on CodePen.

Below, x references y and an update is made to x which changes y. Then x is assigned a value and does not reference y. x is then updated but y is not changed.

See the Pen thecodelog.com - JS By Val By Ref 3 by Deano (@deangilewicz) on CodePen.

Below, x references y and an update is made to x which changes y. x is then updated again which changes y and another time which changes y again.

See the Pen thecodelog.com - JS By Val By Ref 4 by Deano (@deangilewicz) on CodePen.

To effectively pass a compound value (object, array, function) by value-copy, you need to manually make a copy of it, so that the reference passed doesn’t still point to the original.

See the Pen thecodelog.com - JS By Val By Ref 5 by Deano (@deangilewicz) on CodePen.

To pass a primitive value in a way where its value updates take effect, you need to wrap the value in another compound value (object, array, etc.) that can be passed by reference copy. Below, the object reference is passed in to myFn(..) and set to the wrapper parameter. We now can use the wrapper reference to access the shared object, and update its property.

See the Pen thecodelog.com - JS By Val By Ref 6 by Deano (@deangilewicz) on CodePen.