JavaScript Basics Chapter 2: The Data Type Kingdom
· 6 min read
The Story Continues: Chapter 2
Having met the three variable siblings in Chapter 1, we now venture into the diverse kingdom of data types, where every value belongs to a tribe with its own customs and behaviors.
Chapter 2: The Data Type Kingdom
In JavaScript Land, every value belongs to one of several tribes, each with their own customs and behaviors.
The Primitive Tribes
The Number Clan
// All numbers in JavaScript are floating-point
let integer = 42;
let decimal = 3.14159;
let scientific = 2.998e8; // 299,800,000
let negative = -273.15;
// Special number values
let infinity = Infinity;
let negInfinity = -Infinity;
let notANumber = NaN;
// Fun fact: NaN is not equal to itself!
console.log(NaN === NaN); // false (the only value in JS that isn't equal to itself)
console.log(Number.isNaN(NaN)); // true (the correct way to check)
The String Tribe
// Multiple ways to create strings
let single = 'Single quotes';
let double = "Double quotes";
let template = `Template literals with ${single}`;
// String methods are like magical spells
let spell = "Abracadabra";
console.log(spell.length); // 11
console.log(spell.toUpperCase()); // "ABRACADABRA"
console.log(spell.slice(0, 5)); // "Abrac"
console.log(spell.includes("cada")); // true
The Boolean Clan (The Truth Tellers)
let truth = true;
let falsehood = false;
// The fascinating world of truthiness and falsiness
// Falsy values (the "falsy gang"):
console.log(Boolean(false)); // false
console.log(Boolean(0)); // false
console.log(Boolean(-0)); // false
console.log(Boolean(0n)); // false (BigInt zero)
console.log(Boolean("")); // false (empty string)
console.log(Boolean(null)); // false
console.log(Boolean(undefined)); // false
console.log(Boolean(NaN)); // false
// Everything else is truthy!
console.log(Boolean("0")); // true (string "0")
console.log(Boolean([])); // true (empty array)
console.log(Boolean({})); // true (empty object)
The null and undefined Twins
// null: intentional absence of value
let intentionallyEmpty = null;
// undefined: variable exists but has no value
let notYetAssigned;
console.log(notYetAssigned); // undefined
// The confusing part
console.log(typeof null); // "object" (famous JavaScript bug!)
console.log(typeof undefined); // "undefined"
console.log(null == undefined); // true (they're similar)
console.log(null === undefined); // false (but not identical)
The Symbol Tribe (The Unique Ones)
// Symbols are always unique
let sym1 = Symbol("description");
let sym2 = Symbol("description");
console.log(sym1 === sym2); // false - always unique!
// Often used as object keys to avoid conflicts
const PRIVATE_PROP = Symbol("private");
let obj = {
name: "Public",
[PRIVATE_PROP]: "Hidden"
};
The BigInt Giants
// For numbers larger than Number.MAX_SAFE_INTEGER
let huge = 1234567890123456789012345678901234567890n;
let alsoHuge = BigInt("9007199254740991999999");
// Can't mix BigInt with regular numbers
// console.log(huge + 1); // TypeError
console.log(huge + 1n); // Works with BigInt
The Object Kingdom
Objects are the rulers of JavaScript Land, and everything else pays tribute to them.
// Objects are collections of key-value pairs
let kingdom = {
name: "JavaScript Land",
population: Infinity,
ruler: "The Great Function",
// Methods are functions stored as properties
speak: function() {
return `Welcome to ${this.name}!`;
},
// ES6 shorthand for methods
greet() {
return this.speak();
}
};
// Multiple ways to access properties
console.log(kingdom.name); // Dot notation
console.log(kingdom["population"]); // Bracket notation
let prop = "ruler";
console.log(kingdom[prop]); // Dynamic access
Optional Chaining and Nullish Coalescing
// Optional chaining (?.) - safely access nested properties
const user = {
profile: {
social: {
twitter: "@alice"
}
}
};
// Traditional way (verbose and error-prone)
const twitter1 = user && user.profile && user.profile.social && user.profile.social.twitter;
// Optional chaining (clean and safe)
const twitter2 = user?.profile?.social?.twitter;
const instagram = user?.profile?.social?.instagram; // undefined (no error)
// Works with arrays and function calls too
const firstHobby = user?.hobbies?.[0];
const result = user?.getName?.();
// Nullish coalescing (??) - default values for null/undefined
const username = user?.name ?? "Anonymous";
const theme = user?.preferences?.theme ?? "light";
// Different from || operator
console.log("" || "default"); // "default" (empty string is falsy)
console.log("" ?? "default"); // "" (empty string is not nullish)
console.log(null ?? "default"); // "default"
console.log(undefined ?? "default"); // "default"
Dynamic Imports and Top-level Await
// Dynamic imports - load modules conditionally
async function loadModule(condition) {
if (condition) {
const module = await import('./heavy-module.js');
return module.default();
}
}
// Top-level await (in modules)
// utils.js
const data = await fetch('https://api.example.com/data').then(r => r.json());
export { data };
// Code splitting with dynamic imports
const LazyComponent = lazy(() => import('./LazyComponent'));
The Plot Thickens
Now that we’ve met the inhabitants of the Data Type Kingdom, our story takes us to the Operator Guild - a group of symbols that manipulate and compare our data types in fascinating ways.
Continue the adventure:
- Previous: Chapter 1: The Tale of Three Siblings
- Next: Chapter 3: The Operator Guild
- Table of Contents: JavaScript Guide - Table of Contents
“In the Data Type Kingdom, every value has a place and every place has its rules. But beware - some residents aren’t quite what they appear to be!”