Open In App

Reference and Copy Variables in JavaScript

Improve
Improve
Like Article
Like
Save
Share
Report

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.

  1. 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"]
    
  2. 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"]
    
  3. 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"]
    
  4. 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"]
    

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.

  1. 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}
    
  2. 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}
    

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 }


Last Updated : 08 Jul, 2022
Like Article
Save Article
Previous
Next
Share your thoughts in the comments
Similar Reads