Reference and Value Types in Javascript

Ayse Basar
6 min readOct 19, 2022

--

Hi everyone :)

In this very new of my article, I want to explain to you one of the most important cases In Javascript. This subject is asked in interviews most of the time and maybe most people don’t know about it or finds it difficult to understand. I will try to explain it simply as much as I can. I hope you enjoy.

So to begin with,

To be able to understand what is Reference or Value Type, we need to understand what is Heap and Stack in Javascript first.

Heap And Stack

Heap and Stack are actually memory types in Javascript. Javascript has to store assigned values in its memory. So that’s why it has heap and stack. But what are the differences ?

I will explain it deeper but very very shortly,

Heap: is the long time memory of Js.

Stack: is the short-term memory of Js.

Let’s see with a bit of code how this works:

function getUserName () {
return prompt(" ")
}
function displayUserName () {
const userName = getUserName()
return userName
}
displayUserName()

We created a function that takes user’s name and displays it.

Functions are stored in the heap area of Js. I will explain the reason later. But it is not important right now. Let’s just keep this in mind.

So this is how it works simply. I hope it is clear until here.

> Now we can move on to Reference and Value types

As we know, there are two data types in Js: Primitive and Non-primitive

As follows, there are two types in Js: Value Types and Reference Types

> Let’s start with Value Types:

Value Types consist of Strings, Numbers, Booleans, undefined, null and Symbol.

  • Value Types are stored in stack memory. Because they are relatively short living. Js can get rid of them easy. They are cheap to be recreated. So it can easily duplicate them. This does not cost too much memory consuming.
  • They could be stored in the heap as well if it is a long running operation. It’s the browser decides which data ends up where. But they are typically in the stack.
  • The key difference between value and reference types is when you copy a variable which means you assign it to a new one which holds a primitive value, then the VALUE is actually copied. — copying by value —

Let’s see this with an example:

let name = "Ayşe"
let userName = "Ayşe"
name === userName => True
name = "Leyla"
console.log(name) => Leyla
console.log(userName) => Ayşe

As you see in this example, we copied our original variable to a new one and we changed the original one’s value. Original variable has changed but copied variable remained the same. Because it is a copied variable. A change in the original variable does not affect the copied variable.

Let’s see another example:

let x = 10
let y = "abc"
let a = x
let b = y
console.log(x, y, a, b) => 10, "abc", 10, "abc"
let x = 10
let y = "abc"
let a = x
let b = y
a = 5
b = "def"
console.log(x, y, a, b) => 10, "abc", 5, "def"

> Let’s go on with Reference Types:

Reference Types consist of Objects, Arrays, Functions

  • Reference types are stored in the heap area. Js stores a pointer ( address ) in memory. Because they are more complex to manage. Therefore, creating them takes longer. They occupy more memory.
  • So we said that Js stores a pointer. This means the variables store the addresses of that place in memory, not the value itself.
  • Therefore if you copy a variable which holds a reference value, you only copy the pointer ( address, reference ), not the value itself. — copying by reference —

I know it sounds a bit complicated but let’s see with a small picture to understand it better.

And now let’s see it with a bit of code examples:

let hobbies = ["Sports"]
let newHobbies = hobbies
hobbies.push("Dancing")
console.log(hobbies) => ["Sports", "Dancing"]
console.log(newHobbies) => ["Sports", "Dancing"]

Now you might surprise here, because in value types, copied variable did not change. But here both arrays changed. And you will wonder why ?

It is because both variables hold the same address/pointer. We actually copied the original variable’s address here, not the value itself. It means we never copied the array itself. Thus, if you change one array, you automatically change the other.

Same for objects;

let person = { age: 30 }
let newPerson = person
newPerson.age = 32
console.log(person) => { age: 32 }
console.log(newPerson) => { age: 32 }

So How to Copy the Real Values of Arrays/Objects ?

=> Spread Operator

let newPerson = { ... person }
let newHobbies = [ ...hobbies ]
* spread operator pulls out all the key-value pairs or array elements and adds them as new elements, new key-value pairs in a new object/array. So this will mean it will create a new address.

=> Object.assign

let newPerson = Object.assign({}, person)

Let’s move on with some other examples:

const person1 = { age:30 }
const person2 = { age:30 }
console.log(person1 == person2) => false
console.log(person1 === person2) => false

Now you will ask why ? Because they exactly have the same data, they exactly look like the same.

It is because they are actually different objects even if they hold same data because they are at two different addresses in memory. We said that Js creates a pointer for non-primitive datas. So both objects will be created at different addresses. person1 is a different object with its own address/pointer and person2 is a whole different object with its own address/pointer.

But

let person = { age: 30 }
let newPerson = person
console.log( person === newPerson) => True
* Because we copied the address. They hold the same address. We did not create or assign to a new object.

Let’s see another important example:

const hobbies = ["Sports"]
hobbies.push("Dancing")
console.log(hobbies) => ["Sports", "Dancing"]

We think this will throw and error, right ? Because it is a const. Cannot be changed. But it will work. Because again, we store the address in the constant. Data is manipulated, yes but we don’t change array ( the address ) directly. So our array is still at the same address.

But if you try to do this, you will get an error;

const hobbies = ["Sports"]
hobbies = ["Sports", "Dancing"]
console.log(hobbies) => will throw an error

Because you try to change the array ( the address ) directly. Pay attention to the equal sign. The equal sign here tries to assign/create a new array, a new address. And you cannot change your array like this with const.

Same for objects;

const person = { age: 30 }
person.age = 32
console.log(person) => { age: 32 }
* we change the age ( which is a primitive value ) here, not the object itself. The address is still the sameconst person = { age: 30 }
person = { age: 32 } => will throw an error
* because we try to change the object directly. we try to assign a new object, a new address. and const cannot allow this.

So this was all about Value and Reference Types. I hope you enjoyed it and I hope I can be helpful for those who find it difficult to understand.

You can follow me on Medium for more articles.

Cheers :)

--

--