All Articles

Refs vs Copying in JS

This is day 14 in my #javascript30 journey. This is the free course from Wes Bos that lets you brush up on your JavaScript skills via 30 projects.

Yesterday we created some epic transitions using slide in on scroll. You can keep track of all the projects we’re building here.

Today we’re exploring Object and Arrays - Reference VS Copy.


Day 14 - Object and Arrays - Reference VS Copy

Understanding the difference between a reference and a copy is fundamental to understanding JavaScript. Confusing the two can be a mega source of bugs further down the track.

For example, take the following:

let age = 100  
let age2 = age  
console.log(age, age2)  
age = 200  
console.log(age, age2)  

This prints out in the console as:

Console log

This is because when age2 was set the age value was 100. Just because the age variable was later updated doesn’t change the initial value that was set.

This works for strings, numbers, and booleans.

Arrays

Arrays are where it starts getting tricker. When we set a variable to a reference of another array that reference is maintained (no value is specifically set). This means any alterations to the original (or referenced) array will impact both copies.

For instance:

const players = ['Wes', 'Sarah', 'Ryan', 'Poppy']  
const team = players  
console.log(players, team)  
team[3] = "Lux"  
console.log(players, team)  

This prints out in the console as:

Console logging array references

This is because the team variable only ever held a reference to the original array, not a copy.

To make a copy of the array we can use ES6 Spread:

const team = [...players]  

This makes a brand new copy of the players array as the value for team. We can then make an edit on the team array and the players array won’t be impacted:

const players = ['Wes', 'Sarah', 'Ryan', 'Poppy']  
const team = [...players]  
console.log(players, team)  
team[3] = "Lux"  
console.log(players, team)  

Huzzzah

Note: You can also use the following to create a new array but the ES6 spread is the way that we use in our organisation:

const team2 = players.slice()  
const team3 = [].concat(players)  
const team4 = Array.from(players)  
Objects

Objects hold a reference to the original object as well. This requires us to make a copy (much like the arrays).

For example:

const person = {  
  name: 'Stef Cola',
  age: 80,
}
const me = person  
console.log(person, me)  
me.age = 30  
console.log(person, me)  

Prints out as:

Thats not my age

Instead, we make a copy of the original object by creating a new object and assigning the values of the original object:

const me = Object.assign({}, person)  

All wrapped up this looks like:

const person = {  
  name: 'Stef Cola',
  age: 80,
}
const me = Object.assign({}, person)  
console.log(person, me)  
me.age = 30  
console.log(person, me)  

and prints out as:

Yay - object copying rather than referencing

We are also able to add additional attributes to the object or edit the values of the current attributes when copying the object:

const me = Object.assign({}, person, { age: 27, hair: 'blue' })  

This was a great explanation of Object and Array references vs copying them.

You can keep track of all the projects in this JavaScript30 challenge here.