A Journey to the Center of JavaScript
Primitive Values and Reference Values
This week’s #SundayTechMusings is about one of the most feared topics in JavaScript: advanced js. I often see people who are new to front-end development start coding in React or some similar framework. They don’t know enough js but are trying to learn React. I believe this is a huge mistake.
I always tell my students to learn JavaScript first. My sincere advice is that they should learn the logic of code, not copy-paste it. Copying and pasting might solve your problem, but if you don’t understand what you’re doing, it can be very hard to fix any problems that occur.
Understanding how JavaScript works is very important. If you know JavaScript logic, you can easily learn any framework. But a lot of new programmers focus on advanced topics without learning the basics.
In many interviews I conduct with front-end developers, these topics are difficult for candidates. In this series of posts, we’ll look at the most advanced, difficult-to-learn topics, and I will try to explain them in a very basic and simple way.
I’ll divide topics among a few posts. In this first post, we’ll look at primitive values and reference values.
Other topics will include:
- Hoisting
- Closures
- IIFE
- Inheritance and prototype chain
- JavaScript engine and runtime
- Asynchronous JavaScript and event loop (my favorite part)
- .call(), .apply(), .bind()
- ‘this’ keyword
1-) Primitive types and reference types
There are a lot of types used to define variables in js (string, number, array, object, etc.). Unlike in other programming languages, in JavaScript, you don’t have to declare this type.
You may think that all value types behave similarly, but we can separate them into:
- Primitive types: string, number, Boolean, undefined, etc.
- Reference types: array, object, function (anything that is “typeof” object)
What are the differences between primitive and reference types?
On the surface, primitive values and reference values look the same, but under the hood, they behave much differently. The key difference can be seen in how they store their value in memory.
If you looked at the in-memory value of a primitive, you’d see the actual value itself (27
, 'Caglayan'
, false
, etc). If you looked at the in-memory value of a reference type, you’d see a memory address (or a “reference” to a spot in memory).
For example, let’s say we create a variable called name
and assign the string Joe
to it. Then we create a new variable called copyNa
and assign it to whatever the in-memory value name
is, which happens to be Joe
. From there, we change the in-memory value copyName
to be David
. Now, when we log copyName
we get David
, and when we log name
we get Joe
.
Though this example demonstrates that the in-memory value of a primitive is the value itself, there’s nothing surprising or really interesting going on here.
Let’s look at a similar example, but instead of using a primitive value, let’s use a reference value.
First, we create a variable called user
and assign it to an object that has two properties, name
and age
. Then we create a new variable called copyUser
and assign it to whatever the in-memory value of user
is, which is the reference to the spot in memory where the user
object is located.
At this point, both user
and copyUser
are referencing the same spot in memory. So when we modify copyUser.name
, because user
and copyUser
are referencing the same spot in memory, it’s as if we also modified user.name
. That’s why when we log user.name
and copyUser.name
we get the same value, David
.
Let’s look at one more example to cement your understanding. What do you think happens when we use the identity operator (===
), to compare two primitives that have the same value.
Here, we see that because name
and friend
have the same value, Joe
when comparing them, we get true
. This probably seems obvious but it's important to realize that the reason we get true
is because, with the identity operator, primitives are compared by their value. Since both values equal Joe
, comparing them evaluates to true
.
Now, what about reference values?
Even though user
and anotherUser
have the same properties and values, when comparing them with the identity operator, we get false
. The reason for that is because, unlike primitive values, reference values are compared by their reference or their location in memory.
Above, even though user
and anotherUser
have the same properties and values, they're occupying different locations in memory.
Both these examples demonstrate how primitive types are compared by their value while reference types are compared by their reference.
Even two empty objects are not equal, as you can see in line 13.


In the above Figure 2, js stores primitive values in Stack. But it stores reference values in Heap. Object reference addresses are stored in the stack but their values store in the heap.
An interesting by-product of primitive values is that they’re always immutable. This makes sense if you think of primitives in terms of their in-memory value.
We said earlier that if you looked at the in-memory value of a primitive, you’d see the actual value itself. The reason primitive values are always immutable is because whenever you change a primitive value, what you’re actually doing is replacing the in-memory value. Because you can only replace the value and never modify it, that makes it immutable by definition..
MDN summarizes this nicely.
“All primitives are immutable, i.e., they cannot be altered. It is important not to confuse a primitive itself with a variable assigned a primitive value. The variable may be reassigned a new value, but the existing value can not be changed in the ways that objects, arrays, and functions can be altered.”
To sum up, my advice is if you are dealing with objects, you have to be very careful. Because when you think you copy the object, you may corrupt the original data. If you work with copy objects, you have to use shallow or deep copy methods.
This was the first post in this series on advanced JavaScript. If you’re interested, you can follow me on GitHub, Twitter, or LinkedIn to catch more on these topics.
If you find this content helpful and would like to show your support, you can buy me a beer🍺😊
Buy Beer🍺