JavaScript Fundamentals
Master Data Types, Variables & Operators with Interactive Examples
Introduction to JavaScript Fundamentals
Welcome to the comprehensive guide to JavaScript Data Types, Variables, and Operators! These fundamental concepts form the building blocks of every JavaScript program. Whether you're a beginner or looking to refresh your knowledge, this interactive tutorial will guide you through everything you need to know.
Why These Concepts Matter
Understanding data types, variables, and operators is crucial because they are the foundation of all programming logic. Every JavaScript application, from simple scripts to complex web applications, relies on these fundamental concepts.
What You'll Learn
- All 8 JavaScript data types with detailed examples
- Variable declaration with var, let, and const
- All types of operators and their usage
- Best practices and common pitfalls
- Interactive examples and real-world applications
Quick Interactive Demo
// Let's explore basic data types and variables
let name = "JavaScript"; // String
let version = 2024; // Number
let isAwesome = true; // Boolean
let features = ["variables", "functions", "objects"]; // Array
console.log(`Welcome to ${name} ${version}!`);
console.log(`Is JavaScript awesome? ${isAwesome}`);
console.log(`Key features: ${features.join(", ")}`);
JavaScript Data Types
JavaScript has 8 data types that are divided into two categories: Primitive and Reference types. Understanding these types is essential for writing effective JavaScript code.
What are Data Types?
Data types specify what kind of data can be stored and manipulated within a program. JavaScript is a dynamically typed language, which means you don't need to declare the type of a variable explicitly. The type is determined automatically based on the value assigned to the variable.
Primitive Data Types
Primitive data types are immutable (cannot be changed) and are stored directly in the location that the variable accesses. There are 7 primitive data types in JavaScript:
Reference Data Types
Reference data types are mutable and are stored as references to the actual data. There is mainly one reference type in JavaScript:
Object
Represents complex data structures. Objects are collections of key-value pairs. Arrays, functions, and dates are all types of objects.
let person = { name: "John", age: 30 };
let numbers = [1, 2, 3, 4, 5]; // Array object
let currentDate = new Date(); // Date object
typeof {} // "object"
typeof [] // "object"
Data Types Discovery Lab
// Discover all JavaScript data types
console.log("=== PRIMITIVE TYPES ===");
// String
let str = "Hello JavaScript";
console.log(`String: ${str} (type: ${typeof str})`);
// Number
let num = 42;
console.log(`Number: ${num} (type: ${typeof num})`);
// Boolean
let bool = true;
console.log(`Boolean: ${bool} (type: ${typeof bool})`);
// Undefined
let und;
console.log(`Undefined: ${und} (type: ${typeof und})`);
// Null
let nullVal = null;
console.log(`Null: ${nullVal} (type: ${typeof nullVal})`);
// Symbol
let sym = Symbol("unique");
console.log(`Symbol: ${sym.toString()} (type: ${typeof sym})`);
// BigInt
let bigInt = 123456789012345678901234567890n;
console.log(`BigInt: ${bigInt} (type: ${typeof bigInt})`);
console.log("\n=== REFERENCE TYPES ===");
// Object
let obj = { name: "John", age: 30 };
console.log(`Object: ${JSON.stringify(obj)} (type: ${typeof obj})`);
// Array (special type of object)
let arr = [1, 2, 3, 4, 5];
console.log(`Array: [${arr}] (type: ${typeof arr})`);
// Function (special type of object)
let func = function() { return "Hello"; };
console.log(`Function: ${func} (type: ${typeof func})`);
Variables in JavaScript
Variables are containers for storing data values. In JavaScript, we use variables to store and manipulate data throughout our programs. Think of variables as labeled boxes where you can put different types of information.
What are Variables?
Variables are named memory locations that store data values. In JavaScript, variables can hold values of any type and can change their type dynamically during program execution. This flexibility makes JavaScript a powerful and dynamic programming language.
Variable Declaration Methods
JavaScript provides three ways to declare variables: var, let, and const
var vs let vs const
Important Note about var
var is the oldest way to declare variables in JavaScript. While it still works, modern JavaScript development prefers let and const because they have better scoping rules and help prevent common programming errors.
var
- Function-scoped
- Can be redeclared
- Can be updated
- Hoisted (initialized with undefined)
- Older syntax
var name = "John";
var name = "Jane"; // ✓ Works
name = "Bob"; // ✓ Works
let
- Block-scoped
- Cannot be redeclared
- Can be updated
- Not hoisted
- Modern syntax
let age = 25;
let age = 30; // ✗ Error
age = 30; // ✓ Works
const
- Block-scoped
- Cannot be redeclared
- Cannot be updated
- Must be initialized
- Modern syntax
const PI = 3.14159;
const PI = 3.14; // ✗ Error
PI = 3.14; // ✗ Error
Key Takeaway
Use const by default when declaring variables. Only use let if you need to reassign the variable later. Avoid using var in modern JavaScript code.
Variable Scope Experiment
// Demonstrating variable scope and behavior
console.log("=== VAR DEMO ===");
function varDemo() {
var x = 1;
if (true) {
var x = 2; // Same variable!
console.log("Inside if block:", x); // 2
}
console.log("Outside if block:", x); // 2
}
varDemo();
console.log("\n=== LET DEMO ===");
function letDemo() {
let x = 1;
if (true) {
let x = 2; // Different variable!
console.log("Inside if block:", x); // 2
}
console.log("Outside if block:", x); // 1
}
letDemo();
console.log("\n=== CONST DEMO ===");
const person = { name: "John", age: 30 };
console.log("Original person:", person);
// This works - modifying object properties
person.age = 31;
console.log("Modified person:", person);
// This would fail - trying to reassign
// person = { name: "Jane", age: 25 }; // Error!
console.log("\n=== HOISTING DEMO ===");
console.log("Before declaration:", typeof hoistedVar); // "undefined"
var hoistedVar = "I'm hoisted!";
console.log("After declaration:", hoistedVar);
// This would fail - let/const are not hoisted
// console.log("Before declaration:", typeof notHoisted); // Error!
// let notHoisted = "I'm not hoisted!";
JavaScript Operators
Operators are special symbols used to perform operations on variables and values. JavaScript provides various types of operators for different purposes, from basic arithmetic to complex logical operations.
What are Operators?
Operators are used to perform different types of operations on JavaScript variables and values. They can be categorized based on their functionality and the number of operands they work with.
Arithmetic Operators
Arithmetic operators are used to perform mathematical operations between numeric operands:
Comparison Operators
Comparison operators are used to compare two values and return a boolean result:
Important: == vs ===
Always use === (strict equality) instead of == (loose equality) to avoid unexpected type coercion. The same applies to !== vs !=.
Logical Operators
Logical operators are used to combine multiple boolean expressions:
Operators Playground
// Arithmetic Operators Demo
console.log("=== ARITHMETIC OPERATORS ===");
let a = 10;
let b = 3;
console.log(`a = ${a}, b = ${b}`);
console.log(`Addition: ${a} + ${b} = ${a + b}`);
console.log(`Subtraction: ${a} - ${b} = ${a - b}`);
console.log(`Multiplication: ${a} * ${b} = ${a * b}`);
console.log(`Division: ${a} / ${b} = ${a / b}`);
console.log(`Modulus: ${a} % ${b} = ${a % b}`);
console.log(`Exponentiation: ${a} ** ${b} = ${a ** b}`);
// String concatenation with +
console.log(`\nString concatenation: "Hello" + " " + "World" = "${"Hello" + " " + "World"}"`);
console.log("\n=== COMPARISON OPERATORS ===");
let x = 5;
let y = "5";
console.log(`x = ${x}, y = ${y}`);
console.log(`x == y (loose): ${x == y}`);
console.log(`x === y (strict): ${x === y}`);
console.log(`x != y (loose): ${x != y}`);
console.log(`x !== y (strict): ${x !== y}`);
let m = 10;
let n = 20;
console.log(`\nm = ${m}, n = ${n}`);
console.log(`m > n: ${m > n}`);
console.log(`m < n: ${m < n}`);
console.log(`m >= n: ${m >= n}`);
console.log(`m <= n: ${m <= n}`);
console.log("\n=== LOGICAL OPERATORS ===");
let p = true;
let q = false;
console.log(`p = ${p}, q = ${q}`);
console.log(`p && q (AND): ${p && q}`);
console.log(`p || q (OR): ${p || q}`);
console.log(`!p (NOT p): ${!p}`);
console.log(`!q (NOT q): ${!q}`);
// Practical example
let age = 25;
let hasLicense = true;
let canDrive = age >= 18 && hasLicense;
console.log(`\nCan drive (age >= 18 && hasLicense): ${canDrive}`);
// Assignment operators
console.log("\n=== ASSIGNMENT OPERATORS ===");
let num = 10;
console.log(`Initial value: ${num}`);
num += 5; // Same as: num = num + 5
console.log(`After num += 5: ${num}`);
num -= 3; // Same as: num = num - 3
console.log(`After num -= 3: ${num}`);
num *= 2; // Same as: num = num * 2
console.log(`After num *= 2: ${num}`);
num /= 4; // Same as: num = num / 4
console.log(`After num /= 4: ${num}`);
Best Practices & Common Pitfalls
Following best practices in JavaScript helps you write cleaner, more maintainable, and bug-free code. Here are the most important guidelines for working with data types, variables, and operators.
DO: Use const by default
Always use const for variables that won't be reassigned. This prevents accidental modifications and makes your code more predictable.
const PI = 3.14159;
const user = { name: "John" };
const numbers = [1, 2, 3, 4, 5];
DON'T: Use var in modern code
Avoid using var as it has confusing scoping rules. Use let for variables that need to be reassigned, and const for everything else.
var name = "John";
var age = 25;
var isActive = true;
DO: Use strict equality (===)
Always use === and !== instead of == and != to avoid unexpected type coercion and make your comparisons more predictable.
if (age === 25) { ... }
if (name !== "John") { ... }
if (value === null) { ... }
DO: Use descriptive variable names
Choose meaningful variable names that clearly indicate their purpose. This makes your code self-documenting and easier to understand.
const userAge = 25;
const isUserActive = true;
const maximumLoginAttempts = 3;
Pro Tips
- Use template literals (`` ` ``) for string concatenation instead of + operator
- Always initialize variables when declaring them
- Use null for intentional absence of value, undefined for uninitialized variables
- Be careful with floating-point arithmetic - use integers or specialized libraries for precision
- Use typeof operator to check data types, but remember that typeof null returns "object"
Best Practices Validator
// Best Practices Examples
console.log("=== BEST PRACTICES DEMONSTRATION ===");
// 1. Use const by default
const MAX_USERS = 100;
const API_URL = "https://api.example.com";
const DEFAULT_SETTINGS = {
theme: "dark",
language: "en",
notifications: true
};
console.log("Constants:", { MAX_USERS, API_URL, DEFAULT_SETTINGS });
// 2. Use let when reassignment is needed
let currentUser = null;
let isLoading = false;
let attemptCount = 0;
console.log("Initial state:", { currentUser, isLoading, attemptCount });
// 3. Use descriptive names
const calculateUserAge = (birthYear) => {
const currentYear = new Date().getFullYear();
return currentYear - birthYear;
};
const userBirthYear = 1995;
const userAge = calculateUserAge(userBirthYear);
console.log(`User age: ${userAge}`);
// 4. Use strict equality
const userInput = "25";
const expectedAge = 25;
console.log(`userInput == expectedAge: ${userInput == expectedAge}`); // true (bad)
console.log(`userInput === expectedAge: ${userInput === expectedAge}`); // false (good)
// 5. Handle null vs undefined properly
let userData; // undefined
let userPreferences = null; // intentionally null
console.log("userData type:", typeof userData);
console.log("userPreferences type:", typeof userPreferences);
console.log("userPreferences === null:", userPreferences === null);
// 6. Use template literals
const userName = "Alice";
const welcomeMessage = `Welcome, ${userName}! Your age is ${userAge}.`;
console.log(welcomeMessage);
// 7. Check types safely
const checkType = (value) => {
if (value === null) return "null";
if (Array.isArray(value)) return "array";
if (typeof value === "object") return "object";
return typeof value;
};
console.log("Type checks:");
console.log("null:", checkType(null));
console.log("[]:", checkType([]));
console.log("{}:", checkType({}));
console.log("42:", checkType(42));
console.log("'hello':", checkType("hello"));
Real-World Examples & Applications
Let's apply everything we've learned with practical, real-world examples that demonstrate how data types, variables, and operators work together in actual JavaScript applications.
User Profile System
A comprehensive example showing how different data types and operators work together in a user profile management system.
User Profile Management System
// User Profile Management System
console.log("=== USER PROFILE SYSTEM ===");
// User data using different types
const userProfile = {
id: 1,
username: "johndoe",
email: "john@example.com",
age: 28,
isActive: true,
roles: ["user", "admin"],
preferences: {
theme: "dark",
language: "en",
notifications: true
},
lastLogin: null,
profileViews: 0n // BigInt for large numbers
};
// Function to validate user age
const isValidAge = (age) => {
return typeof age === 'number' && age >= 18 && age <= 120;
};
// Function to check user permissions
const hasPermission = (user, permission) => {
return user.roles && user.roles.includes(permission);
};
// Function to format user display name
const formatDisplayName = (user) => {
return `@${user.username} (${user.age})`;
};
// Function to update user preferences
const updatePreferences = (user, newPrefs) => {
return {
...user,
preferences: { ...user.preferences, ...newPrefs }
};
};
// Function to calculate account status
const getAccountStatus = (user) => {
if (!user.isActive) return "Inactive";
if (user.age < 18) return "Minor";
if (hasPermission(user, "admin")) return "Administrator";
return "Standard User";
};
// Demonstrate the system
console.log("Original User Profile:", userProfile);
console.log("\n--- Validation ---");
console.log("Is valid age:", isValidAge(userProfile.age));
console.log("Has admin permission:", hasPermission(userProfile, "admin"));
console.log("Display name:", formatDisplayName(userProfile));
console.log("\n--- Updating Preferences ---");
const updatedUser = updatePreferences(userProfile, {
theme: "light",
language: "es"
});
console.log("Updated preferences:", updatedUser.preferences);
console.log("\n--- Account Status ---");
console.log("Account status:", getAccountStatus(userProfile));
console.log("\n--- Type Checking ---");
console.log("User ID type:", typeof userProfile.id);
console.log("Username type:", typeof userProfile.username);
console.log("Is active type:", typeof userProfile.isActive);
console.log("Roles type:", typeof userProfile.roles);
console.log("Last login type:", typeof userProfile.lastLogin);
console.log("Profile views type:", typeof userProfile.profileViews);
// Calculate some statistics
const userStats = {
totalUsers: 1500,
activeUsers: 1200,
adminUsers: 50,
averageAge: 32.5
};
console.log("\n--- System Statistics ---");
console.log(`Total users: ${userStats.totalUsers}`);
console.log(`Active users: ${userStats.activeUsers}`);
console.log(`Admin users: ${userStats.adminUsers}`);
console.log(`Activity rate: ${(userStats.activeUsers / userStats.totalUsers * 100).toFixed(1)}%`);
console.log(`Average age: ${userStats.averageAge} years`);
// Practical operators usage
console.log("\n--- Operators in Action ---");
const searchQuery = "john";
const foundUser = userProfile.username.includes(searchQuery.toLowerCase());
console.log(`Search for "${searchQuery}": ${foundUser ? "Found" : "Not found"}`);
const isEligibleForFeature = userProfile.age >= 21 && userProfile.isActive;
console.log(`Eligible for premium features: ${isEligibleForFeature}`);
const accountAge = 2; // years
const isLegacyUser = accountAge > 1 || hasPermission(userProfile, "admin");
console.log(`Is legacy user: ${isLegacyUser}`);
E-commerce Price Calculator
A practical example showing how operators and data types work in an e-commerce shopping cart price calculation system.
Shopping Cart Price Calculator
// E-commerce Shopping Cart System
console.log("=== SHOPPING CART CALCULATOR ===");
// Product catalog with different data types
const products = [
{ id: 1, name: "Laptop", price: 999.99, category: "electronics", inStock: true },
{ id: 2, name: "Mouse", price: 29.99, category: "accessories", inStock: true },
{ id: 3, name: "Keyboard", price: 79.99, category: "accessories", inStock: false },
{ id: 4, name: "Monitor", price: 299.99, category: "electronics", inStock: true },
{ id: 5, name: "USB Cable", price: 12.99, category: "accessories", inStock: true }
];
// Shopping cart
const cart = [
{ productId: 1, quantity: 1 },
{ productId: 2, quantity: 2 },
{ productId: 4, quantity: 1 },
{ productId: 5, quantity: 3 }
];
// Discount configuration
const discounts = {
STUDENT: 0.1, // 10% off
SENIOR: 0.15, // 15% off
BULK: 0.05, // 5% off for orders over $500
LOYALTY: 0.08 // 8% off for loyalty members
};
// Tax rate
const TAX_RATE = 0.08; // 8% tax
// Helper functions
const getProductById = (productId) => {
return products.find(product => product.id === productId);
};
const calculateSubtotal = (cartItems) => {
return cartItems.reduce((total, item) => {
const product = getProductById(item.productId);
return total + (product.price * item.quantity);
}, 0);
};
const applyDiscounts = (subtotal, customerType, isLoyaltyMember) => {
let discountAmount = 0;
let appliedDiscounts = [];
// Apply customer type discount
if (discounts[customerType]) {
const customerDiscount = subtotal * discounts[customerType];
discountAmount += customerDiscount;
appliedDiscounts.push(`${customerType}: ${(discounts[customerType] * 100).toFixed(0)}%`);
}
// Apply loyalty discount
if (isLoyaltyMember && customerType !== 'LOYALTY') {
const loyaltyDiscount = subtotal * discounts.LOYALTY;
discountAmount += loyaltyDiscount;
appliedDiscounts.push(`LOYALTY: ${(discounts.LOYALTY * 100).toFixed(0)}%`);
}
// Apply bulk discount for large orders
if (subtotal >= 500) {
const bulkDiscount = subtotal * discounts.BULK;
discountAmount += bulkDiscount;
appliedDiscounts.push(`BULK: ${(discounts.BULK * 100).toFixed(0)}%`);
}
return { discountAmount, appliedDiscounts };
};
const calculateTax = (amount) => {
return amount * TAX_RATE;
};
const formatCurrency = (amount) => {
return new Intl.NumberFormat('en-US', {
style: 'currency',
currency: 'USD'
}).format(amount);
};
// Main calculation function
const calculateTotal = (cartItems, customerType = 'REGULAR', isLoyaltyMember = false) => {
console.log(`Customer Type: ${customerType}`);
console.log(`Loyalty Member: ${isLoyaltyMember ? 'Yes' : 'No'}`);
// Calculate subtotal
const subtotal = calculateSubtotal(cartItems);
console.log(`\nSubtotal: ${formatCurrency(subtotal)}`);
// Apply discounts
const { discountAmount, appliedDiscounts } = applyDiscounts(subtotal, customerType, isLoyaltyMember);
if (appliedDiscounts.length > 0) {
console.log(`Applied Discounts: ${appliedDiscounts.join(', ')}`);
console.log(`Total Discount: -${formatCurrency(discountAmount)}`);
}
// Calculate discounted total
const discountedTotal = subtotal - discountAmount;
console.log(`After Discounts: ${formatCurrency(discountedTotal)}`);
// Calculate tax
const taxAmount = calculateTax(discountedTotal);
console.log(`Tax (${(TAX_RATE * 100).toFixed(0)}%): +${formatCurrency(taxAmount)}`);
// Final total
const finalTotal = discountedTotal + taxAmount;
console.log(`FINAL TOTAL: ${formatCurrency(finalTotal)}`);
return {
subtotal,
discountAmount,
taxAmount,
finalTotal,
appliedDiscounts
};
};
// Demonstrate different scenarios
console.log("--- Scenario 1: Regular Customer ---");
calculateTotal(cart, 'REGULAR', false);
console.log("\n--- Scenario 2: Student Customer ---");
calculateTotal(cart, 'STUDENT', false);
console.log("\n--- Scenario 3: Loyalty Member ---");
calculateTotal(cart, 'REGULAR', true);
console.log("\n--- Scenario 4: Senior Customer + Loyalty ---");
const seniorCart = [...cart, { productId: 3, quantity: 1 }]; // Add out-of-stock item
calculateTotal(seniorCart, 'SENIOR', true);
// Inventory check
console.log("\n--- Inventory Status ---");
const checkInventory = (cartItems) => {
return cartItems.every(item => {
const product = getProductById(item.productId);
return product && product.inStock;
});
};
const canFulfillOrder = checkInventory(cart);
console.log(`Can fulfill order: ${canFulfillOrder ? 'Yes' : 'No'}`);
// Price range analysis
console.log("\n--- Price Analysis ---");
const priceRanges = {
budget: 0,
midRange: 0,
premium: 0
};
cart.forEach(item => {
const product = getProductById(item.productId);
if (product.price < 50) priceRanges.budget += item.quantity;
else if (product.price < 200) priceRanges.midRange += item.quantity;
else priceRanges.premium += item.quantity;
});
console.log("Items by price range:");
console.log(`Budget (< $50): ${priceRanges.budget} items`);
console.log(`Mid-range ($50-$200): ${priceRanges.midRange} items`);
console.log(`Premium (> $200): ${priceRanges.premium} items`);
Interactive Learning Exercises
Test your understanding with these interactive exercises. Try to solve them before running the code to check your answers!
Exercise: Data Type Detective
// Exercise: Data Type Detective
console.log("=== DATA TYPE DETECTIVE EXERCISE ===");
console.log("Test your knowledge! Predict the output before running the code.\n");
// Exercise 1: Type Detection
console.log("Exercise 1: What are the types of these values?");
const mystery1 = "42";
const mystery2 = 42;
const mystery3 = true;
const mystery4 = undefined;
const mystery5 = null;
const mystery6 = { value: 42 };
const mystery7 = [1, 2, 3];
const mystery8 = function() { return 42; };
const mystery9 = Symbol("mystery");
const mystery10 = 42n;
console.log("mystery1 (\"42\"):", typeof mystery1);
console.log("mystery2 (42):", typeof mystery2);
console.log("mystery3 (true):", typeof mystery3);
console.log("mystery4 (undefined):", typeof mystery4);
console.log("mystery5 (null):", typeof mystery5, "(surprise!)");
console.log("mystery6 ({value: 42}):", typeof mystery6);
console.log("mystery7 ([1, 2, 3]):", typeof mystery7);
console.log("mystery8 (function):", typeof mystery8);
console.log("mystery9 (Symbol):", typeof mystery9);
console.log("mystery10 (42n):", typeof mystery10);
// Exercise 2: Operator Precedence
console.log("\nExercise 2: Operator precedence and type coercion");
console.log("2 + '2' =", 2 + '2');
console.log("2 - '2' =", 2 - '2');
console.log("'2' + 2 =", '2' + 2);
console.log("'2' - 2 =", '2' - 2);
console.log("true + true =", true + true);
console.log("true + false =", true + false);
console.log("'hello' + 1 + 2 =", 'hello' + 1 + 2);
console.log("1 + 2 + 'hello' =", 1 + 2 + 'hello');
console.log("null == undefined:", null == undefined);
console.log("null === undefined:", null === undefined);
console.log("0 == false:", 0 == false);
console.log("0 === false:", 0 === false);
console.log("'' == false:", '' == false);
console.log("'' === false:", '' === false);
// Exercise 3: Variable Scope Challenge
console.log("\nExercise 3: Variable scope challenge");
function scopeChallenge() {
var varVariable = "var";
let letVariable = "let";
const constVariable = "const";
if (true) {
var varVariable = "var-modified";
let letVariable = "let-shadowed";
const constVariable = "const-shadowed";
console.log("Inside if block:");
console.log("varVariable:", varVariable);
console.log("letVariable:", letVariable);
console.log("constVariable:", constVariable);
}
console.log("Outside if block:");
console.log("varVariable:", varVariable);
console.log("letVariable:", letVariable);
console.log("constVariable:", constVariable);
}
scopeChallenge();
// Exercise 4: Array and Object Manipulation
console.log("\nExercise 4: Array and object manipulation");
const numbers = [1, 2, 3, 4, 5];
const doubled = numbers.map(n => n * 2);
console.log("Original:", numbers);
console.log("Doubled:", doubled);
const person = { name: "Alice", age: 30, city: "New York" };
const updatedPerson = { ...person, age: 31, country: "USA" };
console.log("Original person:", person);
console.log("Updated person:", updatedPerson);
// Exercise 5: Practical Problem Solving
console.log("\nExercise 5: Practical problem - Grade Calculator");
const calculateGrade = (score) => {
if (typeof score !== 'number' || score < 0 || score > 100) {
return 'Invalid score';
}
if (score >= 90) return 'A';
if (score >= 80) return 'B';
if (score >= 70) return 'C';
if (score >= 60) return 'D';
return 'F';
};
const testScores = [95, 82, 76, 59, 45, 88, 91, 67, 73, 100, -5, 105, "85"];
testScores.forEach(score => {
console.log(`Score: ${score}, Grade: ${calculateGrade(score)}`);
});
// Exercise 6: Advanced Type Checking
console.log("\nExercise 6: Advanced type checking function");
const advancedTypeCheck = (value) => {
if (value === null) return 'null';
if (Array.isArray(value)) return 'array';
if (value instanceof Date) return 'date';
if (typeof value === 'object') return 'object';
if (typeof value === 'function') return 'function';
return typeof value;
};
const testValues = [
42,
"hello",
true,
null,
undefined,
[1, 2, 3],
{ key: "value" },
function() {},
Symbol("test"),
123n,
new Date(),
/regex/
];
console.log("Advanced type checks:");
testValues.forEach(value => {
console.log(`${value} (${typeof value}): ${advancedTypeCheck(value)}`);
});