To talk about passing/copying values in JavaScript we need to talk about data types.
JavaScript data types can be grouped into two categories:
- Simple data types
- Complex data types
Simple data types vs complex data types
The concept of copying/passing data by reference or copying/passing data by value occurs in the face of the difference between these two data types when it comes to assigning variables to variables and data mutation.
Copying by value
Primitive data types like strings, numbers, Booleans, undefined, null, BigInt and symbol are copied by value; that is, two different variables holding primitive values cannot have the same memory address. Let us observe the example bellow:
let myName = "Elijah Gabriel"; // name is pointing at the value "Elijah Gabriel".
let yourName = myName;
console.log(yourName); //prints => "Elijah Gabriel", a copy of myName.
As we can see, while yourName and myName hold the same value, they aren't the same thing in memory. myName has a unique memory address and so does yourName, have its own unique memory address.
Copying by reference
Unlike primitive types, complex data types like arrays and objects in JavaScript are copied or passed by reference; meaning, two different variable names can point to the same data. When an object intended as an object literal or an array object is created, a reference to that object is created and allocated an address in the memory. So, if you create an object and assign it to a new variable, an object reference will be created and both variables will now be pointing at the reference object in memory address.
Example:
let reference = ["Monday", "Tuesday", "Wednesday", "Thursday", "Friday"]; // creates a reference array with a memory address
let refCopy = reference;// now both reference and refCopy are referencing the same array.
Image by Arnav Aggarwal, October 2017.
! diagram showing a referenced data
reference and Copy are pointing at the same array (reference) share the same memory address. This allows us to change properties in one objects or entries in one array and the change will be reflected in all variables pointing at the same reference. This is how it would look:
copy.pop();//
console.log(reCopy) //prints to the console => ["Monday", "Tuesday", "Wednesday", "Thursday"];
console.log(reference); // prints to the console => ["Monday", "Tuesday", "Wednesday", "Thursday"];
As we could see, all changes made to the variable copy affected the variable reference in the same manner, and it would be true vice-versa.
Let us look at an example with objects intended as object literal:
const users = {
firstUser : {firstName: "Tinache",
lastName: "Sabonete",
},
secondUser : { firstName: "Clayde",
lastName: "Magarrafa",
},
};
const usersCopy = users;// both users and usersCopy are pointing at the same object in memory address.
Now, if we change any of the properties in one of the objects, that change will automatically be made in the other object as well, and this is because these two objects share the same reference at this moment. Example:
usersCopy.firstUser = "online";
console.log(users);// prints=> {
firstUser : "online",
secondUser : { firstName: "Clayde",
lastName: "Magarrafa",
},
};
We changed copyUsers, but that change was also reflected on users, and that is because they share a reference.
Breaking reference between arrays or object literals.
Here is a way to break a reference: if the copy variable or the variable reference is assigned to a completely new value, then the reference will be broken, and a new reference-to-be will be created for each of the arrays. Now let's see:
reference = [{weekend: ["Saturday", "Sunday"]}];
console.log(reference);//prints=> [{weekend: ["Saturday", "Sunday"]}].
console.log(copy)// prints => ["Monday", "Tuesday", "Wednesday", "Thursday"].
users = {age: 23, occupation: "student"}
console.log(usersCopy);// prints=> {
firstUser : "online",
secondUser : { firstName: "Clayde",
lastName: "Magarrafa",
},
};// users and usersCopy are now totally different objects and are //stored in different addresses in memory.
The shared reference data between the variable reference and variable copy was broken; copy is still pointing to what the variable reference pointed to when it was created, and now reference points to a totally new value and have a new address in memory.
Conclusion
Simple data types variables have unique memory address, therefore they are passed by value and don't create a reference variable. Complex data type variables are passed by reference because during the variable assignment phase a reference object or object array is created, allowing for multiple variables to share a dwelling address in memory!
Consulted sources:
- https://dustinpfister.github.io/2017/11/13/js-copying-vs-referencing-objects-in-javascript/
- https://codeburst.io/explaining-value-vs-reference-in-javascript-647a975e12a0
- https://www.freecodecamp.org/news/understanding-by-reference-vs-by-value-d49139beb1c4/
- https://codeburst.io/explaining-value-vs-reference-in-javascript-647a975e12a0 .
Top comments (0)