Skip to content

JavaScript Primitives

JavaScript has seven primitive data types that represent the fundamental building blocks of the language. Understanding these primitives is crucial for effective JavaScript programming.

// Different number representations
const decimal = 42;
const octal = 0o755; // 493 in decimal
const hexadecimal = 0xFF; // 255 in decimal
const binary = 0b1010; // 10 in decimal
const scientific = 1.23e10; // 12,300,000,000
const negative = -17;
const float = 3.14159;
// Special numeric values
console.log(Number.MAX_VALUE); // 1.7976931348623157e+308
console.log(Number.MIN_VALUE); // 5e-324
console.log(Number.MAX_SAFE_INTEGER); // 9007199254740991
console.log(Number.MIN_SAFE_INTEGER); // -9007199254740991
console.log(Number.POSITIVE_INFINITY); // Infinity
console.log(Number.NEGATIVE_INFINITY); // -Infinity
console.log(Number.NaN); // NaN
// Static methods
Number.isNaN(NaN); // true
Number.isNaN('hello'); // false (different from global isNaN)
Number.isFinite(42); // true
Number.isFinite(Infinity); // false
Number.isInteger(42); // true
Number.isInteger(42.0); // true
Number.isInteger(42.1); // false
Number.isSafeInteger(42); // true
// Parsing methods
Number.parseInt('42px'); // 42
Number.parseInt('101', 2); // 5 (binary to decimal)
Number.parseFloat('3.14159'); // 3.14159
Number.parseFloat('3.14some'); // 3.14
// Instance methods
const num = 123.456789;
num.toString(); // '123.456789'
num.toString(2); // '1111011.011101001...' (binary)
num.toString(16); // '7b.74bc...' (hexadecimal)
num.toFixed(2); // '123.46'
num.toPrecision(4); // '123.5'
num.toExponential(2); // '1.23e+2'
// Locale-specific formatting
const price = 1234.56;
price.toLocaleString('en-US', {
style: 'currency',
currency: 'USD'
}); // '$1,234.56'
price.toLocaleString('de-DE', {
style: 'currency',
currency: 'EUR'
}); // '1.234,56 €'
// Floating point precision issues
0.1 + 0.2 === 0.3; // false!
0.1 + 0.2; // 0.30000000000000004
// Solution: Use epsilon comparison
function isEqual(a, b) {
return Math.abs(a - b) < Number.EPSILON;
}
isEqual(0.1 + 0.2, 0.3); // true
// Safe integer operations
Number.MAX_SAFE_INTEGER + 1 === Number.MAX_SAFE_INTEGER + 2; // true (unsafe!)
// NaN comparisons
NaN === NaN; // false
Object.is(NaN, NaN); // true
// Infinity arithmetic
Infinity + 1; // Infinity
Infinity / Infinity; // NaN
1 / 0; // Infinity
-1 / 0; // -Infinity
// Type coercion gotchas
'5' - 3; // 2 (string to number)
'5' + 3; // '53' (number to string)
+'42'; // 42 (unary plus converts to number)
// Different string literals
const single = 'Hello World';
const double = "Hello World";
const template = `Hello World`;
const multiline = `
This is a
multiline string
`;
// String with escape sequences
const escaped = 'He said, "Hello!" and walked away.';
const withNewlines = 'Line 1\nLine 2\nLine 3';
const withTabs = 'Column1\tColumn2\tColumn3';
const withUnicode = '\u0048\u0065\u006C\u006C\u006F'; // 'Hello'
// Template literals with expressions
const name = 'JavaScript';
const year = 2024;
const message = `Welcome to ${name} in ${year}!`;
const calculation = `2 + 3 = ${2 + 3}`;
const conditional = `Status: ${year > 2020 ? 'Modern' : 'Legacy'}`;
const str = 'JavaScript Programming';
// Length and character access
str.length; // 21
str[0]; // 'J'
str.charAt(0); // 'J'
str.charCodeAt(0); // 74 (Unicode code point)
str.codePointAt(0); // 74
// Searching methods
str.indexOf('Script'); // 4
str.lastIndexOf('a'); // 15
str.includes('Program'); // true
str.startsWith('Java'); // true
str.endsWith('ming'); // true
str.search(/Script/); // 4 (regex search)
// Extraction methods
str.slice(4, 10); // 'Script'
str.substring(4, 10); // 'Script'
str.substr(4, 6); // 'Script' (deprecated)
// Case methods
str.toLowerCase(); // 'javascript programming'
str.toUpperCase(); // 'JAVASCRIPT PROGRAMMING'
str.toLocaleLowerCase(); // Locale-aware
str.toLocaleUpperCase(); // Locale-aware
// Trimming methods
const padded = ' hello world ';
padded.trim(); // 'hello world'
padded.trimStart(); // 'hello world '
padded.trimEnd(); // ' hello world'
// Replacement methods
str.replace('JavaScript', 'TypeScript'); // 'TypeScript Programming'
str.replaceAll('a', '@'); // 'J@v@Script Progr@mming'
// Splitting and joining
str.split(' '); // ['JavaScript', 'Programming']
str.split(''); // ['J', 'a', 'v', 'a', ...]
'a,b,c'.split(','); // ['a', 'b', 'c']
// Padding methods
'5'.padStart(3, '0'); // '005'
'5'.padEnd(3, '0'); // '500'
// Repeat method
'ha'.repeat(3); // 'hahaha'
// Matching methods
'hello world'.match(/l+/g); // ['ll', 'l']
'hello world'.matchAll(/l/g); // Iterator of match objects
// String normalization (Unicode)
const str1 = '\u00F1'; // ñ (single character)
const str2 = '\u006E\u0303'; // ñ (n + combining tilde)
str1 === str2; // false
str1.normalize() === str2.normalize(); // true
// Locale-specific string comparison
'ä'.localeCompare('z', 'de'); // -1 (ä comes before z in German)
'ä'.localeCompare('z', 'en'); // 1 (ä comes after z in English)
// Regular expressions with strings
const text = 'The year 2024 was amazing!';
const yearRegex = /\d{4}/;
text.match(yearRegex); // ['2024', index: 9, input: '...', groups: undefined]
// Named capture groups
const emailRegex = /(?<local>[^@]+)@(?<domain>[^.]+)\.(?<tld>.+)/;
const email = 'user@example.com';
const match = email.match(emailRegex);
console.log(match.groups); // { local: 'user', domain: 'example', tld: 'com' }
// String interpolation alternatives
function interpolate(template, values) {
return template.replace(/\{\{(\w+)\}\}/g, (match, key) => values[key] || match);
}
interpolate('Hello {{name}}, welcome to {{place}}!', {
name: 'Alice',
place: 'JavaScript'
}); // 'Hello Alice, welcome to JavaScript!'
// Boolean literals
const isTrue = true;
const isFalse = false;
// Boolean constructor (avoid this)
const boolObj = new Boolean(false); // This is an object, not a primitive!
console.log(typeof boolObj); // 'object'
console.log(boolObj.valueOf()); // false
if (boolObj) { // This evaluates to true!
console.log('Boolean objects are truthy');
}
// Proper boolean conversion
Boolean(1); // true
Boolean(0); // false
Boolean('hello'); // true
Boolean(''); // false
Boolean(null); // false
Boolean(undefined); // false
Boolean(NaN); // false
Boolean([]); // true (empty array)
Boolean({}); // true (empty object)
// Double negation (preferred way)
!!1; // true
!!0; // false
!!'hello'; // true
!!''; // false
// Falsy values (only 7 in JavaScript)
const falsyValues = [
false,
0,
-0,
0n, // BigInt zero
'', // empty string
null,
undefined,
NaN
];
// Everything else is truthy
const truthyValues = [
true,
1,
-1,
'hello',
' ', // string with space
[], // empty array
{}, // empty object
function(){}, // function
new Date(), // date object
Infinity,
-Infinity
];
// Practical truthy/falsy checking
function isValid(value) {
return !!value; // Convert to boolean
}
function hasValue(value) {
return value != null && value !== ''; // More specific check
}
// Nullish coalescing vs logical OR
const userInput = '';
const defaultValue = 'Default';
// Logical OR - uses falsy check
const result1 = userInput || defaultValue; // 'Default' (empty string is falsy)
// Nullish coalescing - only null/undefined
const result2 = userInput ?? defaultValue; // '' (empty string is not nullish)
// Creating symbols
const sym1 = Symbol();
const sym2 = Symbol('description');
const sym3 = Symbol('description');
console.log(sym2 === sym3); // false (symbols are always unique)
console.log(sym2.toString()); // 'Symbol(description)'
console.log(sym2.description); // 'description'
// Global symbol registry
const globalSym1 = Symbol.for('app.config');
const globalSym2 = Symbol.for('app.config');
console.log(globalSym1 === globalSym2); // true (same global symbol)
console.log(Symbol.keyFor(globalSym1)); // 'app.config'
console.log(Symbol.keyFor(sym1)); // undefined (not in global registry)
// Symbols as property keys
const sym = Symbol('myProperty');
const obj = {
[sym]: 'secret value',
normalProp: 'normal value'
};
console.log(obj[sym]); // 'secret value'
console.log(obj.sym); // undefined (symbols can't be accessed with dot notation)
// Symbols are not enumerable
Object.keys(obj); // ['normalProp']
Object.getOwnPropertyNames(obj); // ['normalProp']
Object.getOwnPropertySymbols(obj); // [Symbol(myProperty)]
Reflect.ownKeys(obj); // ['normalProp', Symbol(myProperty)]
// Privacy with symbols
const _private = Symbol('private');
class MyClass {
constructor(value) {
this[_private] = value;
this.public = 'public value';
}
getPrivate() {
return this[_private];
}
}
const instance = new MyClass('secret');
console.log(instance.public); // 'public value'
console.log(instance.getPrivate()); // 'secret'
console.log(instance[_private]); // undefined (symbol not accessible)
// Symbol.iterator - defines default iterator
const iterable = {
data: [1, 2, 3],
[Symbol.iterator]() {
let index = 0;
const data = this.data;
return {
next() {
if (index < data.length) {
return { value: data[index++], done: false };
}
return { done: true };
}
};
}
};
for (const value of iterable) {
console.log(value); // 1, 2, 3
}
// Symbol.toStringTag - customize Object.prototype.toString
class MyClass {
get [Symbol.toStringTag]() {
return 'MyClass';
}
}
const instance = new MyClass();
console.log(Object.prototype.toString.call(instance)); // '[object MyClass]'
// Symbol.hasInstance - customize instanceof behavior
class MyArray {
static [Symbol.hasInstance](instance) {
return Array.isArray(instance);
}
}
console.log([1, 2, 3] instanceof MyArray); // true
// Symbol.toPrimitive - customize type conversion
const object = {
[Symbol.toPrimitive](hint) {
if (hint === 'number') {
return 42;
}
if (hint === 'string') {
return 'hello';
}
return true; // default hint
}
};
console.log(+object); // 42 (number hint)
console.log(`${object}`); // 'hello' (string hint)
console.log(object + ''); // 'true' (default hint)
// Creating BigInt values
const big1 = 123n; // BigInt literal
const big2 = BigInt(123); // BigInt constructor
const big3 = BigInt('123456789012345678901234567890');
// BigInt can represent arbitrarily large integers
const maxSafeInt = Number.MAX_SAFE_INTEGER;
console.log(maxSafeInt); // 9007199254740991
console.log(maxSafeInt + 1); // 9007199254740992 (incorrect!)
console.log(maxSafeInt + 2); // 9007199254740992 (same as above!)
const safeBig = BigInt(Number.MAX_SAFE_INTEGER);
console.log(safeBig + 1n); // 9007199254740992n (correct!)
console.log(safeBig + 2n); // 9007199254740993n (correct!)
// BigInt arithmetic
const a = 123n;
const b = 456n;
console.log(a + b); // 579n
console.log(a - b); // -333n
console.log(a * b); // 56088n
console.log(b / a); // 3n (integer division)
console.log(b % a); // 87n
console.log(a ** 2n); // 15129n
// Cannot mix BigInt with regular numbers
try {
console.log(123n + 456); // TypeError!
} catch (error) {
console.log(error.message);
}
// Must convert explicitly
const bigInt = 123n;
const regularInt = 456;
const result = bigInt + BigInt(regularInt); // 579n
// Converting back to Number (be careful with large values)
const smallBig = 123n;
const asNumber = Number(smallBig); // 123
// Comparison works across types
console.log(123n == 123); // true
console.log(123n === 123); // false
console.log(123n < 124); // true
// BigInt methods
const big = 123456789n;
big.toString(); // '123456789'
big.toString(16); // '75bcd15' (hexadecimal)
big.valueOf(); // 123456789n
// Type checking
typeof 123n; // 'bigint'
123n instanceof BigInt; // false (primitives are not instances)
// Math methods don't work with BigInt
try {
Math.sqrt(123n); // TypeError!
} catch (error) {
console.log('Math methods require Number type');
}
// Use BigInt-specific operations
function bigIntSqrt(n) {
if (n < 0n) return null;
if (n === 0n) return 0n;
let x = n;
let y = (n + 1n) / 2n;
while (y < x) {
x = y;
y = (x + n / x) / 2n;
}
return x;
}
console.log(bigIntSqrt(123456789n)); // 11111n
// Undefined - declared but not assigned
let undefinedVar;
console.log(undefinedVar); // undefined
console.log(typeof undefinedVar); // 'undefined'
// Null - intentional absence of value
let nullVar = null;
console.log(nullVar); // null
console.log(typeof nullVar); // 'object' (this is a known quirk!)
// When you get undefined
function noReturn() {
// no return statement
}
console.log(noReturn()); // undefined
const obj = { prop: 'value' };
console.log(obj.nonexistent); // undefined
const arr = [1, 2, 3];
console.log(arr[10]); // undefined
// Explicit undefined assignment
let explicitUndefined = undefined;
// Checking for null and undefined
function isNullOrUndefined(value) {
return value == null; // true for both null and undefined
}
function isStrictlyUndefined(value) {
return value === undefined;
}
function isStrictlyNull(value) {
return value === null;
}
// Nullish coalescing operator (??)
const userInput = null;
const defaultValue = 'default';
const result = userInput ?? defaultValue; // 'default'
// Optional chaining (?.)
const user = {
name: 'Alice',
address: {
street: '123 Main St'
}
};
console.log(user.address?.street); // '123 Main St'
console.log(user.phone?.number); // undefined (no error)
console.log(user.getPhone?.()); // undefined (safe method call)

This comprehensive guide to JavaScript primitives provides the foundation for understanding how data is represented and manipulated in JavaScript. Each primitive type has its unique characteristics and use cases that are essential for effective programming.


Master these primitive types to build a solid foundation for all JavaScript programming concepts.