Understanding JavaScript Primitive vrs Reference Values

Emmanuel Fordjour Kumah - Jan 6 '22 - - Dev Community

Hello World, all programming languages have built-in data types. In JavaScript, there are seven well-known data types.
These data types can be grouped into primitive and reference values.
In this post, we will learn the difference between primitive and reference values in JavaScript.

Understanding the data types

In computer programming, a data type tells the compiler or interpreter what type of value a variable has.

There are seven data types in the JavaScript programming language.

  • undefined
  • null
  • string
  • numbers
  • symbol
  • boolean
  • object

These data types can be grouped into primitive and reference values ( a value can be seen as some kind of data which will be stored in a varaible ).

Primitive data types

There are six primitive data types

  • undefined
  • null
  • string
  • numbers
  • symbol
  • boolean

Non Primitive data type

Object are considered reference or non-primitive values. Keep in mind that arrays and functions are classified as Objects

Storing the data types or values

The JavaScript engine has two places where it store data or values, they are the stack and heap.

Primitive data types do not have complex values, their values are fixed hence stored in the stack.

However, the size of a reference value is dynamic or complex. For instance,

  • An Object can have new properties added to it.
  • An array can have elements added or removed from it.
  • A function can have so many lines of code and more statements being added. Due to all these complexities, we store reference values in the heap.

Assinging values

When you assign a value to a variable, the JavaScript engine will determine whether the value is a primitive or reference value.
This will help determine where to store the variable, either in the stack or heap.

Accessing a primitive value

When you declare a variable and assign a primitive value to the variable, example let a = 40. The JavaScript engine

  • Will allocate some memory or space in the stack
  • Give it a unique identifier which is an address or location to help locate the value when the need be
  • Initialize the variable and assign the value.

Let's see an example

var x = 10;
Enter fullscreen mode Exit fullscreen mode

In the above code:

  • The JavaScript engine will create a unique identifer (Eg. A001) in the browser's memory, and the assignment operator = will now assign or store the value 10 in that specific place we allocated for it (i.e A001).

  • Because the value, 10 is a primitive value, when you access **the variable, you will use or manipulate the **actual value stored in that variable.

  • This means, the variable that stores a primitive value is accessed by value

Copying primitive values

Let's see what happens when you decide to assign a variable that stores a primitive value to another variable.

When you assign any variable that contains a primitive value to a new variable, the value stored in the initial variable is created and copied to the new variable.

Let's take a look at the example below

let a = 40;
let b = a; //assign value stored in`a` to `b`.
Enter fullscreen mode Exit fullscreen mode
  • First we declare a variable a and store a value of 40.
  • Next, we declare another variable b and copy the value stored in a to it. Let's check the output of both variables
console.log(`a =${a} and b = ${b}`)

Enter fullscreen mode Exit fullscreen mode

The output will be

a =40 and b = 40
Enter fullscreen mode Exit fullscreen mode

Anytime a variable is declared, we allocated a location in memory and store the value there.

  • In the above, with let a = 40, we allocated a location **in memory lets call that allocated location **Ax001. Meaning when we go the Ax001, we can have access to the value 40.

  • When we declare b variable, we are also creating a location in the memory so we store a value. Let's call this location Bx001

  • Ax001 and Bx001 will be the location for two places in-memory where we are storing values.

  • Now, we copied the value stored in a to b

let a = 40;
let b = a; //copies value stored in `a` to `b`
Enter fullscreen mode Exit fullscreen mode
  • Internally, JavaScript engine will copy the value stored in a into the location of b (ie. Bx001). Meaning at location Bx001 we now store the value 40.

Changing the initial value

We then decide to change the value we stored in the variable a, would the value stored in variable b change too ?

a = 50; //change value stored in a
console.log(`a =${a} and b=${b})
Enter fullscreen mode Exit fullscreen mode

The output will be

a =50 and b =40
Enter fullscreen mode Exit fullscreen mode

Changing the value stored in a does not change the value stored in b. Eventhough , the value of a has been assigned to b Why ?

This is what is happening

  • The values of variables a and b are stored in different location in memory.

  • The value 40 is stored in the location Ax001 of the variable a whilst what ever value **is stored in variable b will be kept in the location **Bx001.

  • Eventhough we later assign the value stored in a to b, they have been stored in two separate locations.

  • So if you change the value of variable a, it will not change the value stored in variable b.

  • Variables a *and **b * have **no relationship,(due it their different locations in-memory).

In Summary

In summary for primitive values, when you change the value stored in the a variable, the value of the b variable doesn’t change.Because a and b are different locations in memory.

Accessing an non-primitive value

We have mentioned that non-primitive values are stored in the heap this is because non-primitive values have complex data structure so need some huge memory to store it.

When we define a variable and assign a non-primitive data type to it. This is what happens:

  • The JS engine creates a unique identifier or address **eg(NPx001), allocate some memory or space in the heap and store the **actual value at that address

  • Now if the script starts executing and it comes across a non primitive value eg.

user = {
firstName: "Emmanuel",
lastName: "Kumah"
}
Enter fullscreen mode Exit fullscreen mode
  • What the user variable is storing is a pointer, pointing to the **address **where the value is stored and not the actual value.
  • It is not the data value itself, but it tells the variable where to look to find the value.

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).

  • Because the actual value is stored in the heap and we need access to it, we will create a reference ** or some form of pointer on the variable, eg. user and forward ** the location to the value stored in the heap to the user variable

  • Now in the call stack what we have access to, is the *reference * or pointer to the **actual value in the heap**

  • Meanning, when you want to use an object or any non-primitive data type, you work on the reference of that object,rather than the actual object.

When we access a reference value, we manipulate it through reference, not through its actual value that is stored. Thus, variables that are reference values are accessed by reference

Copying reference value

When we assign a variable that stores a reference value to another variable, the value stored in the initial variable is also copied into the location of the new variable.

let user = {
  firstName: "emmanuel",
  location: "Ghana"
}
let admin = user; //assign variable to new variable

console.log(`admin is ${admin.firstName} and user is ${user.firstName}`);
Enter fullscreen mode Exit fullscreen mode

The output will be

admin is emmanuel and user is emmanuel
Enter fullscreen mode Exit fullscreen mode

The difference is, the values stored in both variables will *be the address of the actual object stored on the heap. *

Changing the values

Both variables are referencing the same object. Meaning, we can manipulate the original object from both variables

Let's try and change the firstName property of the user object and see what will happen to properties in admin object.

See the code below

let user = {
  firstName: "emmanuel",
  location: "Ghana"
}
let admin = user; // assign user to admin

console.log(`admin is ${admin.firstName} and user is ${user.firstName}`);

admin.firstName = "Stephen"; //change the firstName property 

console.log(`admin is ${admin.firstName} and user is ${user.firstName}`);

Enter fullscreen mode Exit fullscreen mode

The output will be

admin is emmanuel and user is emmanuel
admin is Stephen and user is Stephen
Enter fullscreen mode Exit fullscreen mode

From the above, when we change the value stored in the user object, it also changed the value stored in the admin object.

We can therefore manipulate the orginal object from both variables, and changing one property in one variable, will change the property in the other variable.

In summary

In this post, we learnt that a varaible can chold one of two value types: primitive values or reference values.

  • Primitive values are data that are stored on the stack.

  • Primitive value is stored directly in the location that the variable acesses.

  • Reference values are objects that are stored in the heap

  • Reference value stored in the variable location is a pointer to a location in memory where the object is stored.

If you found value in this post, kindly share it to your social networks. It will be of value to someone else. Would love to read your comment on this post too.

Written with love from Ghana , me daa se (thank you )

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .