JavaScript Primitives
JavaScript Primitives
Section titled “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.
Number Type
Section titled “Number Type”Number Fundamentals
Section titled “Number Fundamentals”// Different number representationsconst decimal = 42;const octal = 0o755; // 493 in decimalconst hexadecimal = 0xFF; // 255 in decimalconst binary = 0b1010; // 10 in decimalconst scientific = 1.23e10; // 12,300,000,000const negative = -17;const float = 3.14159;
// Special numeric valuesconsole.log(Number.MAX_VALUE); // 1.7976931348623157e+308console.log(Number.MIN_VALUE); // 5e-324console.log(Number.MAX_SAFE_INTEGER); // 9007199254740991console.log(Number.MIN_SAFE_INTEGER); // -9007199254740991console.log(Number.POSITIVE_INFINITY); // Infinityconsole.log(Number.NEGATIVE_INFINITY); // -Infinityconsole.log(Number.NaN); // NaN
Number Methods and Properties
Section titled “Number Methods and Properties”// Static methodsNumber.isNaN(NaN); // trueNumber.isNaN('hello'); // false (different from global isNaN)Number.isFinite(42); // trueNumber.isFinite(Infinity); // falseNumber.isInteger(42); // trueNumber.isInteger(42.0); // trueNumber.isInteger(42.1); // falseNumber.isSafeInteger(42); // true
// Parsing methodsNumber.parseInt('42px'); // 42Number.parseInt('101', 2); // 5 (binary to decimal)Number.parseFloat('3.14159'); // 3.14159Number.parseFloat('3.14some'); // 3.14
// Instance methodsconst 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 formattingconst 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 €'
Number Edge Cases and Gotchas
Section titled “Number Edge Cases and Gotchas”// Floating point precision issues0.1 + 0.2 === 0.3; // false!0.1 + 0.2; // 0.30000000000000004
// Solution: Use epsilon comparisonfunction isEqual(a, b) { return Math.abs(a - b) < Number.EPSILON;}isEqual(0.1 + 0.2, 0.3); // true
// Safe integer operationsNumber.MAX_SAFE_INTEGER + 1 === Number.MAX_SAFE_INTEGER + 2; // true (unsafe!)
// NaN comparisonsNaN === NaN; // falseObject.is(NaN, NaN); // true
// Infinity arithmeticInfinity + 1; // InfinityInfinity / Infinity; // NaN1 / 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)
String Type
Section titled “String Type”String Creation and Literals
Section titled “String Creation and Literals”// Different string literalsconst single = 'Hello World';const double = "Hello World";const template = `Hello World`;const multiline = ` This is a multiline string`;
// String with escape sequencesconst 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 expressionsconst 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'}`;
String Methods
Section titled “String Methods”const str = 'JavaScript Programming';
// Length and character accessstr.length; // 21str[0]; // 'J'str.charAt(0); // 'J'str.charCodeAt(0); // 74 (Unicode code point)str.codePointAt(0); // 74
// Searching methodsstr.indexOf('Script'); // 4str.lastIndexOf('a'); // 15str.includes('Program'); // truestr.startsWith('Java'); // truestr.endsWith('ming'); // truestr.search(/Script/); // 4 (regex search)
// Extraction methodsstr.slice(4, 10); // 'Script'str.substring(4, 10); // 'Script'str.substr(4, 6); // 'Script' (deprecated)
// Case methodsstr.toLowerCase(); // 'javascript programming'str.toUpperCase(); // 'JAVASCRIPT PROGRAMMING'str.toLocaleLowerCase(); // Locale-awarestr.toLocaleUpperCase(); // Locale-aware
// Trimming methodsconst padded = ' hello world ';padded.trim(); // 'hello world'padded.trimStart(); // 'hello world 'padded.trimEnd(); // ' hello world'
// Replacement methodsstr.replace('JavaScript', 'TypeScript'); // 'TypeScript Programming'str.replaceAll('a', '@'); // 'J@v@Script Progr@mming'
// Splitting and joiningstr.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
Advanced String Operations
Section titled “Advanced String Operations”// String normalization (Unicode)const str1 = '\u00F1'; // ñ (single character)const str2 = '\u006E\u0303'; // ñ (n + combining tilde)str1 === str2; // falsestr1.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 stringsconst text = 'The year 2024 was amazing!';const yearRegex = /\d{4}/;text.match(yearRegex); // ['2024', index: 9, input: '...', groups: undefined]
// Named capture groupsconst 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 alternativesfunction 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 Type
Section titled “Boolean Type”Boolean Fundamentals
Section titled “Boolean Fundamentals”// Boolean literalsconst 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()); // falseif (boolObj) { // This evaluates to true! console.log('Boolean objects are truthy');}
// Proper boolean conversionBoolean(1); // trueBoolean(0); // falseBoolean('hello'); // trueBoolean(''); // falseBoolean(null); // falseBoolean(undefined); // falseBoolean(NaN); // falseBoolean([]); // true (empty array)Boolean({}); // true (empty object)
// Double negation (preferred way)!!1; // true!!0; // false!!'hello'; // true!!''; // false
Truthy and Falsy Values
Section titled “Truthy and Falsy Values”// Falsy values (only 7 in JavaScript)const falsyValues = [ false, 0, -0, 0n, // BigInt zero '', // empty string null, undefined, NaN];
// Everything else is truthyconst truthyValues = [ true, 1, -1, 'hello', ' ', // string with space [], // empty array {}, // empty object function(){}, // function new Date(), // date object Infinity, -Infinity];
// Practical truthy/falsy checkingfunction isValid(value) { return !!value; // Convert to boolean}
function hasValue(value) { return value != null && value !== ''; // More specific check}
// Nullish coalescing vs logical ORconst userInput = '';const defaultValue = 'Default';
// Logical OR - uses falsy checkconst result1 = userInput || defaultValue; // 'Default' (empty string is falsy)
// Nullish coalescing - only null/undefinedconst result2 = userInput ?? defaultValue; // '' (empty string is not nullish)
Symbol Type
Section titled “Symbol Type”Symbol Creation and Usage
Section titled “Symbol Creation and Usage”// Creating symbolsconst 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 registryconst 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 Object Keys
Section titled “Symbols as Object Keys”// Symbols as property keysconst 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 enumerableObject.keys(obj); // ['normalProp']Object.getOwnPropertyNames(obj); // ['normalProp']Object.getOwnPropertySymbols(obj); // [Symbol(myProperty)]Reflect.ownKeys(obj); // ['normalProp', Symbol(myProperty)]
// Privacy with symbolsconst _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)
Well-Known Symbols
Section titled “Well-Known Symbols”// Symbol.iterator - defines default iteratorconst 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.toStringclass MyClass { get [Symbol.toStringTag]() { return 'MyClass'; }}
const instance = new MyClass();console.log(Object.prototype.toString.call(instance)); // '[object MyClass]'
// Symbol.hasInstance - customize instanceof behaviorclass MyArray { static [Symbol.hasInstance](instance) { return Array.isArray(instance); }}
console.log([1, 2, 3] instanceof MyArray); // true
// Symbol.toPrimitive - customize type conversionconst 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)
BigInt Type
Section titled “BigInt Type”BigInt Creation and Usage
Section titled “BigInt Creation and Usage”// Creating BigInt valuesconst big1 = 123n; // BigInt literalconst big2 = BigInt(123); // BigInt constructorconst big3 = BigInt('123456789012345678901234567890');
// BigInt can represent arbitrarily large integersconst maxSafeInt = Number.MAX_SAFE_INTEGER;console.log(maxSafeInt); // 9007199254740991console.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 arithmeticconst a = 123n;const b = 456n;console.log(a + b); // 579nconsole.log(a - b); // -333nconsole.log(a * b); // 56088nconsole.log(b / a); // 3n (integer division)console.log(b % a); // 87nconsole.log(a ** 2n); // 15129n
BigInt Limitations and Considerations
Section titled “BigInt Limitations and Considerations”// Cannot mix BigInt with regular numberstry { console.log(123n + 456); // TypeError!} catch (error) { console.log(error.message);}
// Must convert explicitlyconst 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 typesconsole.log(123n == 123); // trueconsole.log(123n === 123); // falseconsole.log(123n < 124); // true
// BigInt methodsconst big = 123456789n;big.toString(); // '123456789'big.toString(16); // '75bcd15' (hexadecimal)big.valueOf(); // 123456789n
// Type checkingtypeof 123n; // 'bigint'123n instanceof BigInt; // false (primitives are not instances)
// Math methods don't work with BigInttry { Math.sqrt(123n); // TypeError!} catch (error) { console.log('Math methods require Number type');}
// Use BigInt-specific operationsfunction 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
Null and Undefined
Section titled “Null and Undefined”Understanding Null and Undefined
Section titled “Understanding Null and Undefined”// Undefined - declared but not assignedlet undefinedVar;console.log(undefinedVar); // undefinedconsole.log(typeof undefinedVar); // 'undefined'
// Null - intentional absence of valuelet nullVar = null;console.log(nullVar); // nullconsole.log(typeof nullVar); // 'object' (this is a known quirk!)
// When you get undefinedfunction 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 assignmentlet explicitUndefined = undefined;
// Checking for null and undefinedfunction 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.