JavaScript Data Types
JavaScript values have a type that determines what you can do with them. There are two categories: primitives and objects.
Primitives are simple, immutable values. Objects are collections of data that can hold multiple values.
Primitive types
JavaScript has seven primitive types.
Number
Numbers cover integers, decimals, and special numeric values.
const age = 28;
const price = 9.99;
const temperature = -5;
Two special number values are worth knowing:
NaN(Not a Number): the result of an invalid maths operation.Infinity: produced by dividing a number by zero.
console.log(10 / 'hello'); // NaN
console.log(1 / 0); // Infinity
String
Strings are text, wrapped in single quotes, double quotes, or backticks (template literals).
const name = 'Anna';
const city = "Copenhagen";
const greeting = `Hello, ${name}!`; // template literal
Boolean
Booleans have two values: true or false. They are used for conditions and flags.
const isLoggedIn = true;
const hasPermission = false;
The following values are considered falsy in JavaScript (they behave like false in a condition): false, 0, '', null, undefined, and NaN. Everything else is truthy.
Undefined
undefined means a variable has been declared but not yet assigned a value.
let score;
console.log(score); // undefined
Null
null represents the intentional absence of a value. You set something to null on purpose to signal it has no value.
const selectedUser = null; // no user selected yet
The difference from undefined: undefined means “not yet assigned”, null means “deliberately empty”.
Symbol (ES2015)
Symbols are unique, immutable identifiers. They are mainly used to create private-ish object property keys that will not clash with other keys.
const id = Symbol('id');
const anotherId = Symbol('id');
console.log(id === anotherId); // false (every Symbol is unique)
Symbols come up in library code and advanced patterns. You will not need them often when starting out.
BigInt (ES2020)
Regular JavaScript numbers have a maximum safe integer value of 2^53 - 1. BigInt lets you work with integers larger than that.
const bigNumber = 9007199254740991n; // note the 'n' suffix
const result = bigNumber + 1n;
console.log(result); // 9007199254740992n
Use BigInt when working with very large numbers, such as database IDs that exceed the safe integer limit.
Objects
Everything that is not a primitive is an object. Objects store collections of key-value pairs.
const user = {
name: 'Anna',
age: 28,
isAdmin: false,
};
Arrays and functions are also objects under the hood, even though they look different.
const colours = ['red', 'green', 'blue']; // array (a type of object)
function greet(name) { // function (also an object)
return `Hello, ${name}`;
}
See the Objects section for a full guide.
The typeof operator
typeof tells you the type of a value. It returns a string.
console.log(typeof 42); // 'number'
console.log(typeof 'hello'); // 'string'
console.log(typeof true); // 'boolean'
console.log(typeof undefined); // 'undefined'
console.log(typeof Symbol()); // 'symbol'
console.log(typeof 1n); // 'bigint'
console.log(typeof {}); // 'object'
console.log(typeof []); // 'object'
console.log(typeof function(){}); // 'function'
One well-known quirk: typeof null returns 'object', even though null is a primitive. This is a long-standing bug in JavaScript that has never been fixed because fixing it would break too much existing code.
console.log(typeof null); // 'object' (this is misleading, but it is how it works)
Type coercion
JavaScript automatically converts types in certain situations. This is called type coercion, and it can catch you off guard.
The + operator with a string triggers string concatenation:
console.log('5' + 3); // '53' (number 3 is converted to string '3')
console.log('5' + '3'); // '53'
Other arithmetic operators force numeric conversion:
console.log('5' - 3); // 2 (string '5' is converted to number 5)
console.log('5' * 2); // 10
console.log('10' / 2); // 5
Always use === for comparisons
The loose equality operator == does type coercion before comparing, which produces results that are hard to predict.
console.log(0 == false); // true (type coercion)
console.log('' == false); // true (type coercion)
console.log(null == undefined); // true (they are treated as equal by ==)
The strict equality operator === compares both value and type, without any coercion.
console.log(0 === false); // false
console.log('' === false); // false
console.log(null === undefined); // false
Use === and !== in your code. The loose versions (== and !=) are rarely what you want.
Common mistakes
Comparing with == instead of ===: The results of == comparisons can be hard to predict. Get into the habit of always using ===.
Assuming null and undefined are the same: They both represent the absence of a value, but they are not identical. null === undefined is false. They are only loosely equal with ==.
console.log(null === undefined); // false
console.log(null == undefined); // true (loose equality only)
See the Variables
page for how types interact with const and let, and the Objects
section for working with object types.