JavaScript Data Types

Home » JavaScript Tutorial » JavaScript Introduction » JavaScript Data Types

Every piece of information you work with in JavaScript—whether it’s text, a number, or a simple true/false value—has a data type. A data type tells the JavaScript engine what kind of information is being stored and what operations can be performed on it.

In JavaScript, all data falls into one of two main categories: Primitives or Objects.

Primitive data types represent a single, simple value. They are the fundamental building blocks of JavaScript. There are seven primitive data types. The typeof operator in JavaScript can be used to determine the type (as seen in examples below), which can be used with or without parentheses, such as typeof(example) or typeof example.

1. The Number type is used for all numeric values, including integers (whole numbers) and floating-point numbers (decimals).

  • Examples: 10, -5.5, 3.14159
  • Special Values: Numbers also include special values like Infinity and NaN (Not a Number). NaN has the data type of number when checked with the typeof operator, which can be confusing for JavaScript beginners. NaN is one of the possible numeric values used to represent the result of an undefined or unrepresentable mathematical operation, like dividing zero by zero.
const integer = 10;
const negative = -5.5;
const PI = 3.14159;

console.log(integer); // Output: 10
console.log(integer + negative); // Output: 4.5
console.log(integer + " " + typeof integer); // Output: 10 number
console.log(negative + " " + typeof(negative)); // Output: -5.5 number
console.log(PI + " " + typeof(PI)); // Output: 3.14159 number

console.log(0 / 0);    // Output: NaN (Not a Number)
console.log(typeof NaN); // Output: number

console.log(Infinity); // Output: Infinity
console.log(1 / 0);    // Output: Infinity
JavaScript

2. The String type is used to store text. Strings are always enclosed in quotation marks, which can be single quotes ('...'), double quotes ("..."), or backticks ( `...`).

  • Examples: "Hello World", 'This is a string!', `I am text`.
let greeting = "This is a string!";
let newGreeting = `I am text`;

console.log(greeting); //Output: This is a string!
console.log(typeof greeting); //Output: string

console.log(newGreeting); //Output: I am text
JavaScript

3. The Boolean type represents a logical entity and can only hold one of two values: true or false.

  • Use: Booleans are essential for several types of JavaScript features such as conditional logic (like if/else statements), Loops, using Logical or Comparison Operators, Ternary Statements, and more to determine which path a program should take.
let isLogged = true;
let hasPermission = false;

console.log(isLogged); // Output: true
console.log(hasPermission); // Output: false
console.log(typeof isLogged); // Output: boolean
console.log(typeof hasPermission); // Output: boolean
JavaScript

4. The null type represents the intentional absence of any object value.

  • Concept: It’s a value explicitly assigned by a developer to indicate “nothing”, “no value”, “empty”, or “value unknown”. Think of it as an empty box. null serves as a deliberate marker. This contrasts with undefined, which usually signifies that a variable has been declared but not yet assigned a value by the JavaScript engine itself.
  • Use: null can be used to release the reference to an object, making it eligible for garbage collection and potentially freeing up memory. In scenarios where a function or API might return an object only under certain conditions, null can be returned to indicate that the object could not be found or created. null clearly conveys the absence of a value, distinct from a numerical zero or an empty string, which are actual values themselves.

In essence, null provides a clear and intentional way to manage the state of variables and properties, distinguishing between an uninitialized state (undefined) and a deliberately empty or non-existent value (null).

let emptyBox = null;
console.log(emptyBox); // Output: null
JavaScript

5. The undefined type means a variable has been declared but has not yet been assigned a value.

  • Concept: If you create a box but don’t put anything in it, it’s undefined. JavaScript assigns this automatically when a let or var variable does not have an initial value assigned to it. undefined my also arise when there is a missing object property, when trying to access an array element outside of the bounds of the array, when there is nothing to return from a function, or when there are missing function arguments.
  • Use: Developers often use the strict equality operator === to check for undefined and handle these cases, such as providing default values for optional parameters or checking if data has been loaded asynchronously. 
// A variable declared without a value:
let myVariable;
console.log(myVariable); // Output: undefined

// Trying to access an Object Property that doesn't exist:
const myObject = {
	name: "Alice"
	//Missing age property
};
console.log(myObject.age); // Output: undefined

// Trying to access the third array index that doesn't exist:
const myArray = [10, 20]
console.log(myArray[2]) //Output: undefined

// Calling a function without passing an argument to the second parameter:
function fullName(firstName, lastName) {
	const greeting = `Hello, ${firstName} ${lastName}!`;
	return greeting;
}
console.log(fullName("Bob")) //Output: Hello, Bob undefined!
JavaScript

6. The BigInt type is a newer primitive used to store integer numbers that are too large to be reliably represented by the standard Number type.

  • Use: Often used in highly specialized mathematical or cryptographic applications. You indicate a BigInt by adding n to the end of a number: 12345678901234567890n.

The largest number JavaScript can safely represent is 9,007,199,254,740,991. When you add a number greater than one to it, the standard Number type often loses precision, resulting in the wrong answer:

const maxSafe = 9007199254740991; // 2^53 - 1
const maxAddTwo = maxSafe + 2;
console.log(maxAddTwo);
// Output: 9007199254740992 
// (INCORRECT! It rounded down to an even number, losing the actual value 9007199254740993)
JavaScript

To create a BigInt, you simply append the letter n to the end of the number. The calculation now retains full precision:

const maxSafeBigInt = 9007199254740991n; // Note the 'n'
const maxAddTwoN = maxSafeBigInt + 2n; // Must add a BigInt to a BigInt
console.log(maxAddTwoN);
// Output: 9007199254740993n
// (CORRECT! Precision is maintained)
JavaScript

This demonstrates simple arithmetic using large numbers with the n suffix.

// A very large population count
const cityPopulation = 10000000000000n; 

// A new development adds 5,000 residents
const newResidents = 5000n; 

// Both operands must be BigInts
const totalPopulation = cityPopulation + newResidents;

console.log(totalPopulation); 
// Output: 10000000005000n

//See the BigInt data type with the typeof operator:
const bigIntExample = 5000n;
console.log(typeof bigIntExample); // Output: bigint
JavaScript

7. The Symbol type is used to create unique and immutable identifiers.

Use: Symbols are guaranteed to be unique and are primarily used in advanced scenarios to create unique object property keys, preventing naming conflicts in large applications.

// 1. Create two new Symbols
const id1 = Symbol('id');
const id2 = Symbol('id');

console.log(id1); // Output: Symbol(id)
console.log(id2); // Output: Symbol(id)

// 2. Check for equality
console.log(id1 === id2); // Output: false 
// Even though they have the same description ('id'), they are NOT equal. 
// Each call to Symbol() returns a new, unique value.
JavaScript

The Symbol.for() method in JavaScript is used to create or retrieve a shared Symbol from a global Symbol registry. Unlike Symbol(), which creates a new and unique Symbol every time it’s called, Symbol.for() allows you to obtain the same Symbol instance across different parts of your code, or even across different realms (like iframes or service workers), as long as they use the same string key.

//Use Symbol.for() to retrieve a shared symbol
const sharedSymbol1 = Symbol.for('mySharedKey');
const sharedSymbol2 = Symbol.for('mySharedKey');

console.log(sharedSymbol1 === sharedSymbol2); // Output: true

//Use Symbol.keyFor() to look up the string key for a Symbol
const retrievedKey = Symbol.keyFor(sharedSymbol2);
console.log(retrievedKey); // Output: mySharedKey
JavaScript

The code example below demonstrates the use of Symbol as a unique, non-string property key in the user object. While standard properties (name, email) and those set by a computed string key (keyExample) are easily accessed and found by enumeration methods like for...in and Object.keys(), the property keyed by the SECRET_ID Symbol is ignored by these methods. This behavior is crucial for the Symbol use cases, as it allows developers to attach internal or metadata properties (like a secret ID) to an object, ensuring they are enumerable (can be retrieved using Object.getOwnPropertySymbols()) but not iterable by general looping constructs, preventing accidental interference or discovery by external code.

// 1. Create a unique Symbol. This is our private/internal key.
const SECRET_ID = Symbol('unique_identifier');

//Variable example using a "computed string key" with user[compPropEx]
const compPropEx = "keyExample"
const user = {
  // Regular string properties
  name: "Alex",
  email: "[email protected]",
  [compPropEx]: "Example Value"
};
console.log(user[compPropEx]); //Output: Example Value

// 2. Add the property using the Symbol as the key
user[SECRET_ID] = "User-54321-ALPHA";

// 3. Accessing the property using the Symbol
console.log(user.name);            // Output: Alex
console.log(user[SECRET_ID]);      // Output: User-54321-ALPHA

// 4. Important: The Symbol key is typically ignored by standard methods
// The 'for...in' loop will skip the Symbol key
console.log("\--- Keys in a for...in loop ---");
for (let objKey in user) { //Loops through user object keys
  console.log(objKey);
}
// Output:
// name
// email
// keyExample

// Object.keys() also skips Symbol keys
console.log("\n--- Keys from Object.keys() ---");
console.log(Object.keys(user)); // Output: [ 'name', 'email', 'keyExample' ]
JavaScript

Unlike the Primitive types (like String or Number) which hold a single, simple value, the Object type is designed for complexity. It is the single non-primitive type in JavaScript and acts as the foundational container for almost everything else.

The most important concept separating Objects from Primitives is that Objects are passed by reference, meaning variables store a pointer to the data’s location in memory, allowing multiple variables to refer to the same data potentially.

When you run the typeof operator on any non-primitive data structure, the result will always be "object", with one notable exception (Functions). This shows that all these complex structures are, fundamentally, specialized objects.

const myObject = {}; //Object Literal Notation
console.log("myObject = " + typeof myObject); //Output: myObject = object

const myObject2 = new Object(); //Object Constructor Function
console.log("myObject2 = " + typeof myObject2); //Output: myObject2 = object

const myArray = []; //Array Literal Notation
console.log("myArray = " + typeof myArray); //Output: myArray = object

const myArray2 = new Array(); //Array Literal Notation
console.log("myArray2 = " + typeof myArray2); //Output: myArray2 = object

function myFunction() {} //Standard function
console.log("myFunction = " + typeof myFunction); //Output: myFunction = function

const arrowFunction = () => {} //ES6 Arrow function
console.log("arrowFunction = " + typeof arrowFunction); //Output: arrowFunction = function

const myDate = new Date(); //Date Object Literal Notation
console.log("myDate = " + typeof myDate); //Output: myDate = object

const myMath = Math; //Math Object (no literal notation without a method)
//Using a math object method results in the "number" data type
console.log("myMath = " + typeof myMath); //Output: myMath = object
JavaScript

Objects like Math and Date are pre-built by the JavaScript engine to perform complex actions. They illustrate that the Object type isn’t just for storing custom data but also for providing utility methods to the language.