Reference and Copy Variables in JavaScript

08 Jul, 2022
In this article, we will talk about pass-by-value and pass-by-reference in JavaScript.JavaScript always passes by value, but in an array or object, the value is a reference to it, so you can ‘change’ the data. JavaScript has 5 primitive data types that are passed by value, they are Boolean, NULL, undefined, String, and Number. It has 3 non-primitive data types that are passed by reference, they are Array, Function, and Object. In non-primitive data types, we have some challenges for copying data. As we know objects are created at some place in the computer’s memory. When we declare any property it creates a space in memory.
Example: The address is a data type that is passed by value just like a number, string, and address points to the location in memory.
Pass by value in case of number.
<script>let age = 100;let age2 = age;document.write(age, age2);document.write("<br>");age = 200;document.write(age, age2); </script>
Output:
100 100
200 100

Pass by value in case of string
<script>let name = 'sam';let name2 = name;document.write(name, name2); document.write("<br>");name = 'xyz';document.write(name, name2); </script>
Output:
sam sam
xyz sam

Pass by reference in case of array
<script>const players = ['Sam', 'Sarah', 'Ryan', 'Poppy'];const team = players;document.write(players, team);</script>
Output:
["Sam", "Sarah", "Ryan", "Poppy"]
["Sam", "Sarah", "Ryan", "Poppy"]

Now if you change the data from “team” array it also affects the “players” array
<script>const players = ['Sam', 'Sarah', 'Ryan', 'Poppy'];const team = players;team[3] = 'xyz';document.write(players, team);</script>
Output:
["Sam", "Sarah", "Ryan", "xyz"]
["Sam", "Sarah", "Ryan", "xyz"]

It’s an array reference, not an array copy. They both point to the same array.We have 4 ways to do it. By using these methods the primary array will not change.
By using slice() method:<script>const players = ['Sam', 'Sarah', 'Ryan', 'Poppy'];const playersCopy = players.slice();playersCopy[2]="west";console.log(players, palyersCopy);</script>Output:["Sam", "Sarah", "Ryan", "Poppy"]
["Sam", "Sarah", "west", "Poppy"]
By using concat() method: Create a new array variable and then concatenate the older one in the new array.<script>  const players = ['Sam', 'Sarah', 'Ryan', 'Poppy'];  const playersCopy2 = [].concat(players);  playersCopy2[2]='hell';  document.write(players, playersCopy2);</script>Output:["Sam", "Sarah", "Ryan", "Poppy"]
["Sam", "Sarah", "hell", "Poppy"]
By using ES6 Spread operator:<script> const players = ['Sam', 'Sarah', 'Ryan', 'Poppy']; const playersCopy3 = [...players]; playersCopy3[3] = 'heeee hawww';  document.write(players, playersCopy3);</script>Output:  ["Sam", "Sarah", "Ryan", "Poppy"]
  ["Sam", "Sarah", "Ryan", "heeee hawww"]
By using Array.from():<script>  const players = ['Sam', 'Sarah', 'Ryan', 'Poppy'];  const playersCopy4 = Array.from(players);  playersCopy4[3]="kim";    document.write(players, playersCopy4);</script>Output:   
["Sam", "Sarah", "Ryan", "Poppy"]
["Sam", "Sarah", "Ryan", "kim"]

By using slice() method:<script>const players = ['Sam', 'Sarah', 'Ryan', 'Poppy'];const playersCopy = players.slice();playersCopy[2]="west";console.log(players, palyersCopy);</script>Output:["Sam", "Sarah", "Ryan", "Poppy"]
["Sam", "Sarah", "west", "Poppy"]

<script>const players = ['Sam', 'Sarah', 'Ryan', 'Poppy'];const playersCopy = players.slice();playersCopy[2]="west";console.log(players, palyersCopy);</script>
Output:
["Sam", "Sarah", "Ryan", "Poppy"]
["Sam", "Sarah", "west", "Poppy"]

By using concat() method: Create a new array variable and then concatenate the older one in the new array.<script>  const players = ['Sam', 'Sarah', 'Ryan', 'Poppy'];  const playersCopy2 = [].concat(players);  playersCopy2[2]='hell';  document.write(players, playersCopy2);</script>Output:["Sam", "Sarah", "Ryan", "Poppy"]
["Sam", "Sarah", "hell", "Poppy"]

<script>  const players = ['Sam', 'Sarah', 'Ryan', 'Poppy'];  const playersCopy2 = [].concat(players);  playersCopy2[2]='hell';  document.write(players, playersCopy2);</script>
Output:
["Sam", "Sarah", "Ryan", "Poppy"]
["Sam", "Sarah", "hell", "Poppy"]

By using ES6 Spread operator:<script> const players = ['Sam', 'Sarah', 'Ryan', 'Poppy']; const playersCopy3 = [...players]; playersCopy3[3] = 'heeee hawww';  document.write(players, playersCopy3);</script>Output:  ["Sam", "Sarah", "Ryan", "Poppy"]
  ["Sam", "Sarah", "Ryan", "heeee hawww"]

<script> const players = ['Sam', 'Sarah', 'Ryan', 'Poppy']; const playersCopy3 = [...players]; playersCopy3[3] = 'heeee hawww';  document.write(players, playersCopy3);</script>
Output:
  ["Sam", "Sarah", "Ryan", "Poppy"]
  ["Sam", "Sarah", "Ryan", "heeee hawww"]

By using Array.from():<script>  const players = ['Sam', 'Sarah', 'Ryan', 'Poppy'];  const playersCopy4 = Array.from(players);  playersCopy4[3]="kim";    document.write(players, playersCopy4);</script>Output:   
["Sam", "Sarah", "Ryan", "Poppy"]
["Sam", "Sarah", "Ryan", "kim"]

<script>  const players = ['Sam', 'Sarah', 'Ryan', 'Poppy'];  const playersCopy4 = Array.from(players);  playersCopy4[3]="kim";    document.write(players, playersCopy4);</script>
Output:
   
["Sam", "Sarah", "Ryan", "Poppy"]
["Sam", "Sarah", "Ryan", "kim"]

Pass by reference in Object: The same point goes for objects, it also affects the original object.
const person = {      name: 'loren isum',      age: 80    };const captain = person;person.age = 25;console.log(captain, person);
Output:
{name: "loren isum", age: 25}
{name: "loren isum", age: 25}

There are two ways to do it.
By using the assign() method:<script>const personObject = {      name: 'loren isum',      age: 80    };const personCopy = Object.assign({},     personObject, { number: 99, age: 12 });personCopy.age = 78;console.log(personCopy, personObject);</script>Output:{name: "loren isum", age: 78, number: 99}
{name: "loren isum", age: 80}
By using the Spread operator:<script>const personData = {      name: 'loren isum',      age: 80    };const personCopy2 = {...personData };personCopy2.age = 78;console.log(personCopy2, personData );</script>Output:{name: "loren isum", age: 78}
{name: "loren isum", age: 80}

By using the assign() method:<script>const personObject = {      name: 'loren isum',      age: 80    };const personCopy = Object.assign({},     personObject, { number: 99, age: 12 });personCopy.age = 78;console.log(personCopy, personObject);</script>Output:{name: "loren isum", age: 78, number: 99}
{name: "loren isum", age: 80}

<script>const personObject = {      name: 'loren isum',      age: 80    };const personCopy = Object.assign({},     personObject, { number: 99, age: 12 });personCopy.age = 78;console.log(personCopy, personObject);</script>
Output:
{name: "loren isum", age: 78, number: 99}
{name: "loren isum", age: 80}

By using the Spread operator:<script>const personData = {      name: 'loren isum',      age: 80    };const personCopy2 = {...personData };personCopy2.age = 78;console.log(personCopy2, personData );</script>Output:{name: "loren isum", age: 78}
{name: "loren isum", age: 80}

<script>const personData = {      name: 'loren isum',      age: 80    };const personCopy2 = {...personData };personCopy2.age = 78;console.log(personCopy2, personData );</script>
Output:
{name: "loren isum", age: 78}
{name: "loren isum", age: 80}

One more thing you need to think about what will happen in the case of an equal and equality operator. When we use these operators on reference type variables they check the reference. If the property has a reference to the same item then the comparison will give output as “true”, otherwise it will return “false.”
<script> var arrayReference = ["Hi!"]; var arrayCopy = arrayReference; console.log(arrayCopy === arrayReference); </script>
Output:
 true

<script>var array1 = ['Hi!'];var array2 = ['Hi!'];console.log(array1 === array2);</script>
Output:
false

This can be corrected by stringifying the array.
<script>var arr1str = JSON.stringify(array1);var arr2str = JSON.stringify(array2);console.log(arr1str === arr2str); // true</script>
Output:
  true

We can change the name property of object person, but we are unable to reset the reference person since it has been marked as const.
<script> const person = {   name: 'Tammy' };  // Name property changed person.name = 'abc';   // Objects are a reference type var val1 = { name: "Tom" };      var val2 = { name: "Tom" };   console.log(val1 == val2)  </script>
Output:
 false

But we can correct this thing by stringifying the array.
<script> var array1 = ['Hi!']; var array2 = ['Hi!']; var arr1str = JSON.stringify(array1); var arr2str = JSON.stringify(array2); console.log(arr1str === arr2str); </script>
Output:
  true

Pass by reference in case of functions: If we pass the object in the function, it will change both the objects.
<script>function changevalue(person) {    var newPersonObj = (person);    newPersonObj.age = 25;    return newPersonObj;}var alex = {    name: 'xyz',    age: 30};var alexChanged = changevalue(alex);console.log(alex); console.log(alexChanged); </script>
Output:
{ name: 'xyz', age: 25 }
{ name: 'xyz', age: 25 }

We can resolve this problem by parsing and stringifying the object.
<script>function changevalue(person) {    var newPersonObj = JSON.parse(JSON.stringify(person));    newPersonObj.age = 25;    return newPersonObj;}var alex = {    name: 'xyz',    age: 30};var alexChanged = changevalue(alex);console.log(alex); console.log(alexChanged);  </script>
Output:
  { name: 'xyz', age: 30 }
  { name: 'xyz', age: 25 }

JavaScript-Misc
JavaScript
Web Technologies
Writing code in comment?
Please use ide.geeksforgeeks.org,
generate link and share the link here.
Difference between var, let and const keywords in JavaScript
Differences between Functional Components and Class Components in React
Remove elements from a JavaScript Array
Roadmap to Learn JavaScript For Beginners
Difference Between PUT and PATCH Request
Installation of Node.js on Linux
Top 10 Projects For Beginners To Practice HTML and CSS Skills
Difference between var, let and const keywords in JavaScript
How to insert spaces/tabs in text using HTML/CSS?
How to fetch data from an API in ReactJS ?