JavaScript data types are an essential piece to understanding modern JavaScript.
A data type is a classification of data. Programming languages need to have different data types to interact properly with values.
A data type in a language defines the type of data a variable can hold.
You can do math with a number, but not with a sentence, so the computer classifies them differently.
Data types help to provide a better understanding of the language and its behavior. Hence, in this article, we will discuss the various data types in JavaScript in detail. So let’s start.
What are data types in JavaScript?
Like other programming languages, Data types in JavaScript are used to specify the type of data a variable can hold and determine the operations that can be performed on it.
But, why do we need data types?
In JavaScript, there are different data types to hold different types of values. In our daily life, we deal with different types of data such as string, number, and sometimes boolean (True or False).
For example, the name of a person is of string type, age is of number type, and many others.
As mentioned earlier if a variable is a container to hold values, the data type is the type of container that tells what type of value or data it can store.
Let’s see an example:
let name = "Rahul"; let age=32;
Here,
- Rahul is a string data.
- 32 is a number data.
JavaScript is both dynamically and weakly (loosely) typed
JavaScript is not statically typed unless you are using a language tool such as Typescript that compiles to JavaScript code. But we will briefly cover it here for comparison reasons.
Statically typed means the type is enforced and won’t change so easily.
That means, all variables must be declared with a type.
int x = 5; string y = 'abc';
Dynamically typed language such as JavaScript infer variable types at runtime. This means once your code is run the compiler/interpreter will see your variable and its value then decide what type it is.
The type is still enforced here, it just decides what the type is.
var a = 1 // int b = 'test' // string // etc
JavaScript is also a weakly (loosely) typed language, meaning you don’t have to specify what type of information will be stored in a variable in advance.
JavaScript automatically types a variable based on what kind of information you assign to it (e.g., that ''
or " "
to indicate string values).
Many other languages, like Java, require you to declare a variable’s type, such as int
, float
, boolean
, or string
.
Lets take an example:
var x = ' '; console.log(typeof x); //output - string
💡 The typeof Operator
The typeof
operator can be used to find out what type of data a variable or operand contains. It can be used with or without parentheses (typeof(x)
or typeof x
).
JavaScript has two categories of data types
There are total eight data types in JavaScript which can be divided into two main categories:
- Primitive Data types
- Non-primitive (reference) Data types
The following table highlights primitive and non-primitive data types:
Primitive | Non-primitive |
undefined | Object |
Boolean | |
Number | |
String | |
BigInt | |
Symbol | |
null |
Primitive Data types
Primitive type means which holds only a single value be it a String
or a Number
or whatever.
var name = 'Sunil'; //hold single value console.log(name); //output - Sunil console.log(typeof name); //output - String
Non-primitive (reference) Data types
Non-primitive (reference) data types can hold collections of data and more complex entities.
const student = { firstName: 'Sunil', lastName: 'Pradhan', class: 10 };
Non-primitive Data types memory is allocated at the heap
Also, these data types are mutable, i.e. they can be altered or changed.
Let’s discuss each one of them in detail.
🤔 Primitive type VS. Reference type
Primitive data types are base data types whereas reference data types are derived.
Memory allocation in primitive data types happens in “Stack” whereas memory allocation in reference data types happens in “Heap” (Dynamic memory).
JavaScript String Data Type
String
is used to store text. In JavaScript, strings are surrounded by quotes:
- Single quotes:
'Hello'
- Double quotes:
"Hello"
- Backticks:
`Hello`
For example,
//strings example const name = 'ram'; //output - ram const name1 = "hari"; //output - hari const result = `The names are ${name} and ${name1}`; //output - The name are ram and hari
Single quotes and double quotes are practically the same and you can use either of them.
Backticks are generally used when you need to include variables or expressions into a string. This is done by wrapping variables or expressions with ${variable or expression}
as shown above.
🤔 What is an expression in JavaScript?
A fragment of code that produces a value is called an expression.
Example: 5 * 10;
//5 * 10 evaluates to 50
JavaScript Boolean Data Type
Boolean type can either be True or False. A truthy value simply means yes and a falsy value means no.
For example:
let a = 2; let b = 7; let c = 10; console.log(b > a); //output: true console.log(a > c); //output: false
Thus Boolean
is a logical data type which can be used for comparison of two variables or to check a condition.
JavaScript Number Data Type
The Number
data type is used to represent positive or negative numbers with or without decimal place, or numbers written using exponential notation e.g. 1.5e-4 (equivalent to 1.5×10-4).
In other words, Number
type represents integer and floating numbers (decimals and exponentials).
For example,
const number1 = 3; const number2 = 3.433; const number3 = 3e5 // 3 * 10^5
A number type can also be +Infinity
, -Infinity
, and NaN
(not a number). For example,
const number1 = 3/0; console.log(number1); // Infinity const number2 = -3/0; console.log(number2); // -Infinity // strings can't be divided by numbers const number3 = "abc"/3; console.log(number3); // NaN
🤔 Infinity and NaN
Infinity represents the mathematical Infinity ∞
, which is greater than any number. Infinity is the result of dividing a nonzero number by 0.
While NaN
represents a special Not-a-Number value. It is a result of an invalid or an undefined
mathematical operation, like taking the square root of -1 or dividing 0 by 0, etc.
JavaScript BigInt Data Type
In JavaScript, Number
type can only represent numbers less than (253 – 1) and more than -(253 – 1). However, if you need to use a larger number than that, you can use the BigInt
data type.
A BigInt
number is created by appending n to the end of an integer. For example,
// BigInt value const value1 = 900719925124740998n; // Adding two big integers const result1 = value1 + 1n; console.log(result1); // "900719925124740999n" const value2 = 900719925124740998n; // Error! BitInt and number cannot be added const result2 = value2 + 1; console.log(result2);
JavaScript Undefined Data Type
The undefined
data type represents value that is not assigned, that means if a variable is declared, but not assigned, then its value is undefined
:
For example:
let name; console.log(name); // undefined
It is also possible to explicitly assign a variable value undefined
.
For example:
let name = undefined; console.log(name); // undefined
💡 Note
It is recommended not to explicitly assign undefined
to a variable. Usually, null
is used to assign ‘unknown’ or ’empty’ value to a variable.
JavaScript Null Data Type
In JavaScript, null
is a special value that represents “nothing”, “empty” or “value unknown”.
let x = null; console.log(typeof x); //output - object
Here variable is empty so that it is at the beginning behave as a placeholder which you will use to put something inside of it.
The value does not go to undefined
so that you have to put initially null
which later you can change it to a value.
Why is null an Object?
The ECMAScript documentation lists it as a primitive type, yet its typeof
returns object
.
Basically, this is a bug that isn’t fixed because it would break existing code. This bug has been around since the first version of JavaScript.
The bug comes from the typeof
function in the JavaScript source — We will use some pseudo code to simplify it.
//pseudo typeof if(is_undefined) { return 'undefined' } else if(is_an_object) { if(object_is_a_function) { return 'function' } else { //must be an object return 'object' } }
Did you catch the bug? It didn’t check for null
. Read more about the rejected fix proposal here and see this part of the JS source here.
JavaScript Symbol Data Type
Symbol
data type was introduced in ES6 and it is a unique and immutable data type.
A Symbol is a unique and immutable primitive value and may be used as the key of an Object property.
Its main feature is that each Symbol
is a completely unique token, unlike other data types which can be overwritten.
The Symbol
data type also defines a property of an object which is private to the object. It refers to the ‘key’ of the key-value pair of an object.
var object1 = { name: 'Sunil', age: 25, city: 'Bangalore' } var occupation=Symbol('engineer');
The function Symbol()
is used to create a new symbol. Here we have created a symbol ‘occupation’ with the value ‘engineer’ for the above object ‘object1’.
Every symbol is unique. Two Symbols even with the same key values are not same.
var object1 = { name: 'Sunil', age: 25, city: 'Bangalore' } var occupation=Symbol('engineer'); var occupation=Symbol(); console.log(Symbol('engineer') === Symbol()); //false
Thus both the above ‘occupation’ symbols are different. Each one is a unique property of the object.
💡 Note
Note that Symbol
is a function, not an object constructor, therefore, you cannot use the new
operator. If you do so, you will get a TypeError
.
All of these primitive types have two things in common:
- They are immutable: they cannot change. If you change them, you are just creating a new one.
- They don’t have any methods or properties.
A primitive is not an object and has no methods of its own.
If primitive data types don’t have methods or properties, then, how can we use string.toUppercase()
? or any of the other methods that primitives have.
This is possible because some of the primitives have their equivalent in the objects world. That means that we use string
type when we declare a string, but we use String
object when we use some of the methods or properties on it.
Also, do not confuse constructors with primitives — every primitive has a constructor or parent object.
JavaScript knows when you are trying to access a method on a primitive and behind the scenes, it will use the constructor to make an object out of your primitive. Once it runs the method that object is then garbage collected. ( removed from memory )
See some examples below.
const str = 'a'; str instanceof String; // false typeof str; //'string' const arr = [1, 2, 3]; arr instanceof Array; //true typeof arr; // 'object'
Strings are in fact primitives as described in the article, not entire objects. JavaScript knows when you try to access a method on the String
object and coerces your primitive into a string object.
When it’s done the temporary object is garbage collected and life continues as usual.
const strObj = new String('abc'); const prim= 'def'; typeof strObj //'object' strObj /*String {"abc"} 0: "a" 1: "b" 2: "c" length: 3 __proto__: String [[PrimitiveValue]]: "abc" */ prim // 'def' const newStr = strObj + prim //'abcdef' typeof newStr //'string'
Read more about this in the YDKJS book by Kyle Simpson.
JavaScript Object Data Type
In JavaScript, an object is a collection of properties, where each property is defined as a key-value pair.
You can imagine an object as a container, with the content of the container changing with time. We declare them in curly brackets { }
.
For example,
var car = { name: 'BMW X3', color: 'white', doors: 5, }; console.log(car);
We created an object with three properties here: name, color, and doors.
There are many other objects too just to list a few:
- Array
- Function
- RegExp
❓ Why we use primitives instead of having everything as an object?
The answer is: because of how memory is handled.
JavaScript uses two kinds of memories: Memory Heap and Memory Stack.
Memory Stack, is where primitives are saved. This memory is smaller, but it’s faster than Memory Heap. On the other hand, Memory Heap is bigger, but slower.
So what JavaScript does is that it saves primitives and a reference to objects into the Memory Stack and saves the complete object into the Memory Heap.
That’s why we cannot copy objects that easy in JavaScript.
More info @dev.to
FAQs
Further Reading
- Record and Tuples – New Datatypes in JavaScript
- JavaScript data types and data structures – MDN Web Docs
- JavaScript data types: ES5, ES6, ES2016 (ES7)
- ECMAScript® 2022 Language Specification
Conclusion
In this tutorial, you have learned JavaScript primitive and non-primitive data types including undefined, null, number, string, Boolean, symbol, object and others.
We hope now you have gained a good knowledge of data types in JavaScript. Until then, Stay Happy, Stay safe. Keep coding! Thank you for reading.
Add comment