Hi Devs! Today we will discuss one of the most fundamental concept in Javascript "Pass by Value" and "Pass by Reference". This concept is so important, even this question is often pop up in job interview. Why is that? By understanding how this works, it will help us to be a better programmer that can understand the flow of data in the application.
Before we can dive in into the explanation. We must know that, in Javascript data types are classified into two categories: primitive and non-primitive.
Here is a list primitive data types in Javascript:
string
-- an array of characternumber
-- integer, floats, etc...bigint
-- in case you need integer values larger than the range supported by theNumber
boolean
-- true or falsenull
-- empty valuesymbols
-- an unique value or often used as unique identifier that is not equal to any other valueundefined
-- declared variable but the value is still not assigned.
Meanwhile all objects, arrays, and functions fall under the category of non-primitive data types.
Okay, we got this. Let's jump into the explanation!
Pass by Reference
Let's take a look at the code below to understand what is pass by reference is
let john = {
name: 'John Doe',
gender: 'male',
score: 95
};
let JohnDupe = john;
console.log(JohnDupe); // {name: 'John Doe', gender: 'male', score: 95}
console.log(john); // {name: 'John Doe', gender: 'male', score: 95}
Okay, we have create a new variable JohnDupe
and assign the value from John
. What happen next if we modify the score of JohnDupe
?
johnDupe.score = 50;
console.log(JohnDupe); // {name: 'John Doe', gender: 'male', score: 50}
console.log(john); // {name: 'John Doe', gender: 'male', score: 50}
Notice that the value score of John
is also changed! What actually happened? When we create John
(new object), we are store the value in the memory within some address. And when we assign the value from John
to johnDupe
, actually instead of creating a copy of John
, JohnDupe
value is referencing the value (the address) of John
in the memory.
To fix the problem above, we need to actually create a copy of John
and assign it to a new variable and then we can change the score without affecting the original John
.
let john = {
name: 'John Doe',
gender: 'male',
score: 95
};
let anotherJohn = {...john}
anotherJohn.score = 50;
console.log(john); // {name: 'John Doe', gender: 'male', score: 95}
console.log(anotherJohn); // {name: 'John Doe', gender: 'male', score: 50}
In the code above, we have copied john
using spread operator and then assign it into anotherJohn
. By creating new object, anotherJohn
actually store the copied object in the memory with different address from john
. anotherJohn
is not referencing john
anymore like before, they are completely a different entities. To prove that, take a look at the code below
let person = {
name: 'Nicola Tesla',
gender: 'male',
};
let personDupe = person;
let anotherPerson = {
name: 'Nicola Tesla',
gender: 'male',
};
console.log(person === personDupe); // true
console.log(person === anotherPerson); // false
In the example above, we tried to compare equal person === personDupe
which will be print true
because personDupe
is pointing the address from person
. However when we tried to compare equal person === anotherPerson
this will be print false
because they are not the same object even if they are have the same properties and values.
This behavior is also same with Array
.
let fruits = ['apple ๐', 'strawberry ๐', 'banana ๐'];
let fruitsDupe = fruits;
let anotherFruits = ['apple ๐', 'strawberry ๐', 'banana ๐'];
console.log(fruits === fruitsDupe); // true
console.log(fruits === anotherFruits); // false
I have an analogy for having us easier to understanding "pass by reference" by assuming it as a google sheet / google docs.
Let's say a group of student is given an assignment by a teacher to put their own opinion about global warming. ๐ The teacher want the format of the assignment to be in a single file.
John as the class president take the initiative to create a google docs so the student could collaborate easily. John then share the link with his classmates. Mary is the first student that make a change into the docs and add a bunch of paragraph of her idea about global warming. Later that night Suzie opened the google docs and add her own opinion, followed by Andy and so on. Finally after all the student is finished add their own opinion, John shared the google docs to the teacher. All is good and the class got an "A" for the assignment โจ
From the case above, no matter how many times google docs is modified by students in the end it still be only modifiying one file (master file).
So far so good! We are know what is exactly pass by reference is. โจ
Pass by Value
If you are already understanding pass by reference, you already understanding pass by value is. Primitive values such as numbers or strings will actually create a copy.
const num = 10
function passByValue(val) {
return val += 1
}
console.log('[passByValue]:', passByValue(num)) // [passByValue]: 11
console.log('[num]:', num) // [num:] 10
In the code above, we create a variable num
with the value of 10. Also we create a function passByValue
which take a value as parameter and add it by 1. If we were trying to run the code above, passByValue
will return 11, however num
variable is still 10. the original value of num
is not changed at all.
I hope this short article will help you to understanding the concept of pass by reference and pass by value. The main difference between pass by value and pass by reference is, pass by value will create a new space in memory and make a copy of a value. Pass by reference however instead of making a copy, the value stored in memory gets referenced.
Top comments (7)
Damn, this is so brilliant comment!!!
Exactly, there are just NOT any ways to mutate primitive data type value:
You missed
bigint
on the primitives listThanks Jon, added! I rarely use it, so I think I missed it ๐
Wow, I might will check it out. Thank you!
Maybe you made a typo error because in Javascript everything is passed as Reference, not Value.
Proof :
If it where by value, object would not have changed.
It is still pass by value. In this case, the value passed for obj is a reference to an object, which is why the state of the object passed for obj can change. However, if you tried to do something like
obj = someOtherObject
inside of that function, the change is only observable inside of that function. If it was pass by reference, that change would also be observable by the caller. But it is not.Oh, yeas, my bad.
Objects are references is the right explaination. At first you wrote : "Now objects are mutable and hold references to values" witch i interpreted as "Now Objects are mutable and properties hold references to values" which my example disproved.
But yes, One single Object is by itself stored as a reference to the actual object.
Proof