Skip to content

Basic data types in JavaScript

June 18, 2025

13 min read

JavaScript has dynamic data types that change automatically. You can assign different types to the same variable, and the interpreter handles conversion. In this article, I’ll go through all the important data types in JavaScript, including primitive types and objects, and explain how they work.

Number

JavaScript uses the number type to represent both integers and floating-point numbers. There are many operations for numbers, such as multiplication *, division /, addition +, subtraction -, and so on. Any numeric literal can be preceded by a minus sign (-) to make the number negative.

let num = 100;
let price = 12.5;
let discount = 0.05;
let negativeNumber = -10;

Note that JavaScript automatically converts a floating-point number to an integer if the number appears to be a whole number. The reason is that JavaScript always wants to use less memory, because a floating-point value uses twice as much memory as an integer value. For example:

let price = 100.00; // Interpreted as an integer 100

This type has a certain range, and if you work with large numbers, you can get the type’s range using Number.MIN_VALUE and Number.MAX_VALUE.

console.log(Number.MIN_VALUE); // 5e-324
console.log(Number.MAX_VALUE); // 1.7976931348623157e+308

JavaScript represents numbers using the 64-bit floating-point format defined by the IEEE 754 standard,1 which means it can represent numbers as large as ±1.7976931348623157 × 10308 and as small as ±5 × 10−324.

In addition to regular numbers, there are so-called “special numeric values” that also belong to this data type: Infinity, -Infinity, and NaN.

When the result of a numeric operation is greater than the largest representable number (overflow), the result is the special infinite value Infinity. Similarly, when the absolute value of a negative value becomes greater than the absolute value of the largest representable negative number, the result is negative infinity, -Infinity.

console.log(1 / 0); // Infinity
console.log(-1 / 0); // -Infinity
console.log(Number.MAX_VALUE + Number.MAX_VALUE); // Infinity
console.log(-Number.MIN_VALUE - Number.MIN_VALUE); // -Infinity

NaN

NaN represents a computational error and is a special numeric value that indicates an invalid number. It is the result of an incorrect or undefined mathematical operation (such as 0/0). If NaN appears anywhere in a mathematical expression, it propagates to the entire result (meaning that once you get NaN as a result, any further mathematical operation with NaN will return NaN).

console.log( "not a number" / 2 ); // NaN, such  division is erroneous
console.log(NaN / 2); // NaN, division by NaN is also erroneous
console.log(NaN == NaN); // false, NaN is not equal to itself
console.log('a' / 2); // NaN, division by a string is also erroneous

JavaScript supports numeric literals in several formats. The most commonly used are Integer Literals and Floating-Point Literals.

Integer Literals

JavaScript numeric literals include integer literals in various bases as well as floating-point literals in base-10. In addition to base-10 integer literals, JavaScript recognizes hexadecimal (base-16) values.

// Decimal integer literal
0 
12
1000000

// Hexadecimal integer literals
0xFF
0x3b24

// Binary integer literal
0b1010

// Octal integer literal
0o12

Floating-Point Literals

Floating-point literals can have a decimal point; they use traditional syntax for real numbers. They can also be represented using exponential notation: a real number followed by the letter e (or E), followed by an optional plus or minus sign, followed by an integer exponent.

3.1415926
.123456789
3.1E+12
.1e-23

Rounding Errors

In his book JavaScript: The Definitive Guide, David Flanagan notes that when working with numbers in JavaScript, you’ll encounter situations where not all numbers are always equal, even though it may appear so at first glance.

When you’re working with real numbers in JavaScript, the representation of the number will often be an approximation of the actual number.

JavaScript numbers have great precision and can approximate a given number very closely. But the fact that this number cannot be expressed exactly can lead to problems. Look at the following code:

let a = 0.1 + 0.2; // 0.30000000000000004
let b = 0.3; // 0.3
console.log(a === b); // false, because 0.1 + 0.2 is not exactly equal to 0.3
let c = 0.1 + 0.2 - 0.3; // 5.551115123125783e-17
console.log(c); // 5.551115123125783e-17, a very small number close to zero

In the example, you might expect c to equal 0, but it actually equals a very small number close to zero: approximately 5.551115123125783e-17.

It’s good to know that this problem is not specific to JavaScript: it affects any programming language that uses binary floating-point numbers.

Dates and Time

JavaScript dates and times provide built-in functions for working with dates, times, and time zones. They allow developers to easily create, manipulate, format, and compare dates and times in their applications.

These functions provide support for various time zones and allow developers to work with dates and times in different regions and cultures.

let timestamp = Date.now(); // The current time as a timestamp (a number)
let now = new Date(); // Current date and time as a Date object
let ms = now.getTime(); // Convert to a milliseconds
let iso = now.toISOString(); // Convert to a string in standard format

BigInt

In JavaScript, the number type cannot safely represent integer values larger than (2^53-1) (which is 9007199254740991) or smaller than -(2^53-1) for negative values. Therefore, the BigInt type was recently added to the language, which represents integers of arbitrary length.

A BigInt value is created by appending n to the end of an integer:

let bigInt = 1234567890123456789012345678901234567890n;

Since BigInt numbers are rarely needed, I won’t describe this type in much detail. You can learn more about it on the MDN website.

Boolean

This is a logical data type that takes only two values: 0 (false) or 1 (true), and is used for evaluating conditions, loops, etc. This type is commonly used to store yes/no values: true means “yes, correct” and false means “no, incorrect”.

let isActive = true; // true
let isLoggedIn = false; // false

Boolean values are also the result of comparisons, as you can see in the following example, where I stored the result of a comparison in a variable:

let isGreater = 4 > 1; // true
alert(isGreater); // true (the comparison result is "yes")

JavaScript allows values of other types to be converted to boolean values true or false. To convert a value of another data type to a boolean value, use the Boolean() function.

console.log(Boolean("Hi")); // true
console.log(Boolean(""); // false

console.log(Boolean(20)); // true
console.log(Boolean(Infinity)); // true
console.log(Boolean(0)); // false
console.log(Boolean({foo: 100})); // true on non-empty object

console.log(Boolean(null)); // false
console.log(Boolean(undefined)); // false
console.log(Boolean(NaN)); // false

Null

The special value null does not belong to any of the above-described types and forms a separate type that contains only the null value. This is a special value that represents “nothing”, “empty”, or “unknown value”. In JavaScript, null is not a “reference to a non-existent object” or a “null pointer” as in some other languages.

As you can see in the example below, I assign the variable age the value null, which means that the age is unknown:

let age = null; // The age is unknown

Null and undefined (which I will describe in the following section) return the value true, which could mean that these values are equal. In practice, it’s a bit more complex, but for understanding, it’s sufficient to know that both types have similar meaning.

console.log(null == undefined); // true

If we used the === operator, we would get false as a result, because the values do not have the same data types. It’s the same as with other types.

console.log("0" == false) // true, because "0" is converted to a number 0
console.log("0" === false) // false, because "0" is a string and false is a boolean

Undefined

The undefined type is a primitive type that has only one undefined value. By default, when a variable is declared but not initialized, it is assigned the value undefined. Undefined means that the variable has been declared, but the value of this variable has not yet been defined.

In the following example, I create a variable, but since it has no value, this variable is not initialized. Therefore, both the value and type are undefined.

let counter;
console.log(counter); // undefined
console.log(typeof counter); // "undefined"

It’s important to realize that the output from the typeof function (which returns what data type it is) will also be undefined if you call it on a variable that has not been declared.

String

In JavaScript, a string is a sequence of zero or more characters. It is an immutable ordered sequence of values (16-bit), each of which typically represents a Unicode character. For simplicity, we can think of it as a string of letters or characters. In some variants, it can be theoretically infinite and is limited only by the size of RAM memory.

A string literal begins and ends with either a single quote ('), double quote ("), or backticks (`). A string that begins with a double quote must end with a double quote. Similarly, a string that begins with a single quote must also end with a single quote, etc.

  • Double quotes: “Hello”.
  • Single quotes: ‘Hello’.
  • Backticks: `Hello`.
"" // empty string
'Hello, world!'
"3.14"
'name="John Doe"' 
"Hi, How Are You"
`"Who said 'Hi'", somebody asked.`

Notice that backticks are used for Template literals and the result doesn’t always have to be a string. For simplicity, however, I’m also mentioning this variant as one of the writing options. It’s mainly used in cases where we need to include both double quotes or single quotes in the string.

const fruit = "apple";
const color = "red";
console.log(`This ${color} ${fruit} is delicious and
not like a ${color} ${fruit.replace('apple', 'orange')}.`);
// "This red apple is delicious and
// not like a red orange."

However, we can achieve the same effect if we use a backslash. The backslash character () has a special purpose in JavaScript strings.

let foo = 'You can\'t do that!';
let foo2 = 'You\'re right! I can\'t be a quote.';

The backtick syntax in ES6 also allows splitting strings across multiple lines:

'more\nlines\nare\npossible'
"one\nmore\nline"

String immutability

JavaScript strings are immutable, which means they cannot be modified after creation. However, you can create a new string from an existing string. For example:

let str = "JavaScript";
str = str + " is serious language!";

The result will be "JavaScript is serious language!", because JavaScript created a new string str and destroyed the original string.

In this example, what happened was:

  1. First, we declared a variable str and initialized it to the string "JavaScript".
  2. Then we use the + operator to concatenate "JavaScript" with " is serious language!" and expect the value of str to change to "Javascript is serious language!".
  3. However, this didn’t happen because the JavaScript engine creates a new string that contains the string "JavaScriptis serious language!" and destroys the original strings "JavaScript" and "is serious language".

For better understanding, try the following example:

let str = "JavaScript";
str[0] = "j"; // This will not change the first character
console.log(str); // "JavaScript", the original string remains unchanged

This statement creates a variable a and assigns it the string "JavaScript". Then it unsuccessfully attempts to replace the first character of the string from J to j.

Again, this won’t work, precisely because it’s an immutable data type; just like all primitive values in JavaScript.

String operators

One of JavaScript’s built-in features is the ability to concatenate strings. If we use the + operator with the number data type, JavaScript will add the numbers. But if we use this operator for strings, it will join them by appending the second to the first.

let name = "John Doe";
let message = "Hello, " + "world!"; // Produces the string "Hello, world!"
let greeting = "Hello, " + " " + name ; // "Hello, John Doe"

Strings can be compared using standard equality (===) and inequality (!==) operators. Two strings are equal if and only if they consist of exactly the same sequence of values.

Strings can also be compared with operators <, <=, > and >= and this works by comparing 16-bit values. Strings are compared character by character in alphabetical order and a lowercase letter is always greater than an uppercase letter. The comparison itself is a more complex topic, so I recommend exploring the documentation.

const a = "a";
const b = "b";
if (a < b) {
  console.log(`${a} is less than ${b}`); // Return true, "a is less than b"
} else if (a > b) {
    console.log(`${a} is greater than ${b}`); // This won't be executed
} else {
    console.log(`${a} is equal to ${b}`); // This won't be executed
}

Note that all comparison operators compare strings character by character in alphabetical order, according to case sensitivity.

Object

The object type is special. In JavaScript, an object is a collection of properties, where each property is defined as a key-value pair. All other types are called “primitive” because their values can contain only one thing (a string, number, etc.). In contrast, objects serve to store collections of data and more complex entities.

Since this type is important, it deserves more attention, and therefore I won’t elaborate on this type in greater detail again. If you’re interested, I recommend reading about this type, for example, again on MDN.

However, we can look at the following example for illustration, which defines an empty object:

let person = {}; // An empty object

Notice the curly brackets syntax, which indicates that this is an object data type.

If we want to define a person object with two properties: firstName and lastName, the code might look something like this:

let person = {
  firstName: "John",
  lastName: "Doe"
};

The name of an object property can be any string, and if it’s not a valid identifier, you can use quotes around the property name. It’s also good to realize that an object property can contain another object:

let person = {
  firstName: "John",
  lastName: "Doe",
  email: "john.does@example.com",
  phone: "123-456-7890",
  age: 43,
  address: {
    street: "North 1st Street",
    city: "San Francisco",
    state: "CA",
    zip: "94101"
  }
};

Symbols

The symbol type is used to create unique identifiers for objects. JavaScript added the primitive symbol type in ES6, and unlike other primitive types, the symbol type doesn’t have a literal form.

I mention this type only for completeness, but elaborating on details in this overview is not my goal. If you’re interested, you can take a look at the specification.

The typeof operator

Since we’ve covered all the basic data types in JavaScript, there’s one function that will come in handy for determining what type we’re dealing with. This function is called typeof and we can use it to check data types. This is especially useful when we want to process values of different types in different ways.


typeof undefined; // "undefined"
typeof 0; // "number"
typeof 10n // "bigint"
typeof true; // "boolean"
typeof "foo"; // "string"
typeof Symbol("foo"); // "symbol"
typeof { foo: "bar" }; // "object"
typeof null; // "object" (this is a historical bug in JavaScript)

Notice how in the last example JavaScript perceives the null type, and this is due to the first implementation of JavaScript. Even though a proposal for change appeared, it was rejected. You can read about the specific reason on the MDN and detailed information is available in the web archive.

Summary

JavaScript has several data types, including primitive and non-primitive types. It’s good to have a solid understanding of the various data types available in a programming language like JavaScript so you can program effectively.

Sometimes you’ll get by with basic knowledge, and other times you’ll need to find more detailed information. It all depends on what you’re currently working on. Don’t forget that you can always look up information in the documentation on MDN or in books like The Definitive Guide by David Flanagan.

See all posts