JavaScript Primitive & Reference Types

Introduction

In my perspective, it is crucial to understand the types of a certain programming language because it is the building block. That’s why in this article, will see the builtin types of JavaScript and the difference between primitive and reference types.

Moreover, coming from a static-typed language like C# and jumping to JavaScript, I became confused due to its dynamic behavior. The funny thing was I was looking for classes and realized that it has no formal support (Classes, as you may know, from languages like Java/C#, don’t technically exist in JavaScript). It was strange at first but I became accustomed. Thus, I decided to create this article to help students or developers alike to share my knowledge and journey learning JavaScript types.

Background

When I started with JavaScript, many fantastic developers argue that JavaScript doesn’t have types. Particularly those developers who came from strongly-typed languages like C#, Java, and C++. Back then, I honestly don’t know what to say because I’m not that knowledgeable yet. However; today If you ever encountered or will encounter these kinds of developers you can point them to the JavaScript language specification. I’ll give the link below and a screenshot that states that the JavaScript language does have types.

As of this writing, we have the “ECMAScript 2020 Language Specification”, which can be found here. Lastly, let us see what the specification has to say concerning types. Please see the screenshot below.

I hope that saves your day. Now, enough of that, let’s jump into the JavaScript built-in types.

JavaScript Data Types

The JavaScript language has two kinds of types: primitive types and reference types. Primitive types (termed as value types too) are stored as simple data types while reference types are stored as objects, which means it holds a reference to a memory’s location.

When using JavaScript and dealing with its different types, primitive and reference they may seem the same but it isn’t. Correct? You can answer on the comment section below. Moreover, to make the language consistent, it lets you treat primitive types as reference types.

Here is the list of JavaScript built-in types:

  • boolean
  • number
  • bigint
  • string
  • null
  • undefined
  • symbol
  • object

Primitive Types

TypesDescriptionRemarks
Booleantrue or false | 1 or 0
NumberAny integer or floating-point numeric value. Any double precision IEEE 754 number.
BigIntLarge integers even beyond the safe integer limit for Number.A BigInt is created by appending n to the end of an integer.
You can check here if it is supported by your browser.
StringUTF-16 string. The sequence of characters delimited by either single or double- quotes.
NullSpecial primitive-type that has only one value, null. I called it special because it is, will discuss this in a later section (Why null returns object?).
UndefinedA primitive type that has only once value, undefined.The undefined keyword is the value assigned to a variable that wasn’t initialized.
SymbolA unique and immutable value.For more information about Symbol, you can read more here.

Let us see some examples of primitive types below.

//boolean
var iLoveJavaScript = true; 

//number
var yearsOfCoding = 10; 

//bigint
var bigIntSample = 1234567890987654321n;

//string
var programmerName = "Jin Vincent Necesario";

//null
var doesntPointToAny = null; 

//undefined
var badCompany; //undefined

How Primitive Types Behave?

Primitive types are always assigned, the value is copied.

To practically see the behavior, let’s look at the example below.

var name1 = "Jin";
var name2 = name1;

console.log(name1); //Jin
console.log(name2); //Jin

name2 = "Vincent";

console.log(name1); //Jin
console.log(name2); //Vincent

If you would like to see what’s happening, please see the Figure-1 below.

javascript-primitive-types-memory-stack
Figure 1

As you can see the variable name1 and name2 are completely separate from each other, and you can change the value in name2 without affecting name1 and vice versa.

Using the typeof Operator

The typeof Syntax

//typeof operand
//or 
//typeof(operand)

The typeof operator is the best way to identify types that returns the type in string format. The operand is the expression representing the primitive or reference type.

Let us see some examples below.

//typeof operator without using the open and close parentheses
console.log(typeof true);//boolean

console.log(typeof 10);//number

console.log(typeof bigIntSample); //bigint

console.log(typeof "Jin Vincent Necesario");//string

console.log(typeof null);//object -> oops! more about this later

console.log(typeof undefined);//undefined
//end typeof operator without using the open and close parentheses

//typeof operator using the open and close parentheses
console.log(typeof(true));//boolean

console.log(typeof(10));//number

console.log(typeof(bigIntSample)); //bigint

console.log(typeof("Jin Vincent Necesario"));//string

console.log(typeof(null));//object -> oops! more about this later

console.log(typeof(undefined));//undefined
//end typeof operator using the open and close parentheses

Why null returns object?

OK, you have probably run the code samples above and wondering why the null data-type returns object. This is the tricky part of the language, even me I was confused at first but no worries will answer that here.

The truth, it is a bug and it has been acknowledged by TC39, the committee that maintains the JavaScript language. One reason this bug wasn’t fixed because the proposed fix broke a number of existing sites. Thus, the error remained. For more information about it, you can read more here.

Now, that we have an idea of why it behaves that way. What’s the best way to determine if a value is null? To do this, you can compare the null directly against its value. See the example below.

var myObject1 = null;
console.log(myObject1 === null); //true

Reference Types

If you are coming from another language like C#, Java, or C++, reference types are the closest thing to classes. Reference values are instances of reference types. Moreover, reference types do not store the object directly into the variable to which it is assigned. Thus, it holds a reference to the location in memory where the object exists.

Make Objects

There are various ways to create objects in JavaScript. And these are: using new operator, object literal, and a constructor function.

Let’s see an example below.

var myObject2 = new Object(); //using the new operator
console.log(typeof(myObject2));//object

var myObject3 = {};//using the object literal ({})
console.log(typeof (myObject3));//object

//using the constructor function
function MyUnknownObject(property1, property2) {
    
    this.property1 = property1;
    this.property2 = property2;

}

var myObject4 = new MyUnknownObject("JavaSript", 23);
console.log(typeof (myObject4));//object

How Objects Behave?

Let us see an example below.

var _object1 = new Object();
_object1.favoriteLanguage = "JavaScript";

var _object2 = _object1; 

console.log(_object1);//output:{favoriteLanguage: "JavaScript"}
console.log(_object2);//output:{favoriteLanguage: "JavaScript"}

_object1.favoriteLanguage = "C#";

console.log(_object1);//output: {favoriteLanguage: "C#"}
console.log(_object2);//output: {favoriteLanguage: "C#"}
Output

As you can see, we have declared a new object using the variable _object1 and assigned it to _object2. As a result, both of them are referencing the same object. That’s why any changes to either one of them have the same effect.

If you would like to see what’s happening, please see the Figure-2 below.

Figure 2

Destroy Objects

Garbage collection – frees objects when they are not used anymore (garbage-collected). JavaScript is one of those languages that have this kind of feature built into it. Thus, you don’t really need to worry about manual memory allocations when you use reference types.

Moreover, you might have a false impression that you don’t need to deference your objects. Thereby, it’s best to dereference objects that you no longer need. In order for the garbage collector to free up that memory space. In order for us to do this is to set the object variable to null.

Difference between Primitive Types and Reference Types

The main difference between the two is that primitive types directly contain their values. Meaning, when you assign a primitive value to a variable, the value is copied into that variable. While reference types don’t store the object directly into the variable to which it is assigned. Instead, it holds the reference to the location in memory where the object exists.

Summary

In this post, we have tackled the JavaScript primitive and reference types. We have started by listing the builtin types and shown the primitive types and reference types. Moreover, we have seen how to use the typeof operator and how to create and destroy an object. Lastly, we have differentiated the primitive and reference types.

I hope you have enjoyed this article, as I have enjoyed writing it. Stay tuned for more. Don’t forget to subscribe, if you haven’t subscribed yet. Many thanks, until next time, happy programming!