javascript

exercises

exercises.js
/**
 * ============================================
 * 2.2 Data Types - Exercises
 * ============================================
 *
 * Practice working with JavaScript data types.
 * Solutions are at the bottom.
 */

// ============================================
// EXERCISE 1: Type Identification
// ============================================
// For each value, write the result of typeof and actual type

// 1a) 42                    typeof: _____ actual: _____
// 1b) "42"                  typeof: _____ actual: _____
// 1c) true                  typeof: _____ actual: _____
// 1d) null                  typeof: _____ actual: _____
// 1e) undefined             typeof: _____ actual: _____
// 1f) Symbol("id")          typeof: _____ actual: _____
// 1g) 42n                   typeof: _____ actual: _____
// 1h) []                    typeof: _____ actual: _____
// 1i) {}                    typeof: _____ actual: _____
// 1j) function(){}          typeof: _____ actual: _____

// ============================================
// EXERCISE 2: Number Operations
// ============================================
// Predict the output of each operation:

// 2a) 0.1 + 0.2 === 0.3     Output: _____
// 2b) 1 / 0                  Output: _____
// 2c) "hello" - 5            Output: _____
// 2d) NaN === NaN            Output: _____
// 2e) typeof NaN             Output: _____
// 2f) parseInt("42px")       Output: _____
// 2g) parseInt("px42")       Output: _____
// 2h) Number("42.5abc")      Output: _____

// ============================================
// EXERCISE 3: String Manipulation
// ============================================
// Write code to solve each task:

let str = 'JavaScript is awesome!';

// 3a) Get the length of the string
// Your code:

// 3b) Convert to uppercase
// Your code:

// 3c) Check if it includes "awesome"
// Your code:

// 3d) Replace "awesome" with "amazing"
// Your code:

// 3e) Get the first 10 characters
// Your code:

// 3f) Split into array of words
// Your code:

// ============================================
// EXERCISE 4: Template Literals
// ============================================
// Rewrite using template literals:

let product = 'Laptop';
let price = 999.99;
let inStock = true;

// Original: "The " + product + " costs $" + price + " and is " + (inStock ? "available" : "out of stock")

// Your template literal version:

// ============================================
// EXERCISE 5: Truthy and Falsy
// ============================================
// Mark each value as Truthy (T) or Falsy (F):

// 5a) 0           _____
// 5b) ""          _____
// 5c) "0"         _____
// 5d) []          _____
// 5e) {}          _____
// 5f) null        _____
// 5g) undefined   _____
// 5h) NaN         _____
// 5i) "false"     _____
// 5j) -1          _____

// ============================================
// EXERCISE 6: Null vs Undefined
// ============================================
// For each scenario, which should you use: null or undefined?

// 6a) A function parameter that wasn't provided
// Answer: _____

// 6b) A user explicitly clears their profile picture
// Answer: _____

// 6c) A search that found no results
// Answer: _____

// 6d) A variable declared but not yet assigned
// Answer: _____

// 6e) An API response field that doesn't exist
// Answer: _____

// ============================================
// EXERCISE 7: Symbol Practice
// ============================================
// Create a user object with:
// - Regular property: name = "John"
// - Symbol property: id = 12345 (using Symbol for privacy)
// - Show that Object.keys() doesn't include the symbol

// Your code:

// ============================================
// EXERCISE 8: BigInt
// ============================================
// Solve these BigInt problems:

// 8a) Create a BigInt for 9007199254740993 (larger than MAX_SAFE_INTEGER)
// Your code:

// 8b) Add two BigInts: 100n and 200n
// Your code:

// 8c) Why does this fail? Fix it.
// let result = 100n + 50;
// Your fix:

// 8d) Compare: Is 1n equal to 1? (loose vs strict equality)
// Your code:

// ============================================
// EXERCISE 9: Reference vs Value
// ============================================
// Predict the output:

let x = 10;
let y = x;
y = 20;
// console.log(x);  // Output: _____

let arr1 = [1, 2, 3];
let arr2 = arr1;
arr2.push(4);
// console.log(arr1);  // Output: _____

let obj1 = { a: 1 };
let obj2 = { ...obj1 }; // Spread operator
obj2.a = 2;
// console.log(obj1.a);  // Output: _____

// ============================================
// EXERCISE 10: Type Checking Function
// ============================================
// Create a function getType(value) that returns accurate type names:
// - "null" for null
// - "array" for arrays
// - "number", "string", etc. for primitives
// - "object" for plain objects

// Your code:

// ============================================
// EXERCISE 11: Number Validation
// ============================================
// Create a function isValidNumber(value) that returns true only for:
// - Actual numbers (not NaN)
// - Finite numbers (not Infinity)
// - Not BigInt

// Your code:

// ============================================
// EXERCISE 12: String Analysis
// ============================================
// Create a function analyzeString(str) that returns an object with:
// - length: number of characters
// - words: number of words
// - hasNumbers: boolean (contains digits)
// - hasSpaces: boolean (contains spaces)

// Your code:

// ============================================
// EXERCISE 13: Truthy/Falsy Converter
// ============================================
// Create a function that takes any value and returns:
// - "falsy: [type]" if the value is falsy
// - "truthy: [type]" if the value is truthy

// Example: classifyValue(0) → "falsy: number"
// Example: classifyValue("hello") → "truthy: string"

// Your code:

// ============================================
// EXERCISE 14: Safe Property Access
// ============================================
// Given this nested object, safely access these values:
// If value doesn't exist, return "Not found"

let data = {
  user: {
    profile: {
      name: 'John',
      settings: {
        theme: 'dark',
      },
    },
  },
};

// 14a) Get user.profile.name

// 14b) Get user.profile.age (doesn't exist)

// 14c) Get user.profile.settings.theme

// 14d) Get user.preferences.language (doesn't exist)

// ============================================
// EXERCISE 15: Type Coercion Puzzle
// ============================================
// Predict the output (this is tricky!):

// 15a) [] + []           // _____
// 15b) [] + {}           // _____
// 15c) {} + []           // _____
// 15d) true + true       // _____
// 15e) "5" + 3           // _____
// 15f) "5" - 3           // _____
// 15g) null + 1          // _____
// 15h) undefined + 1     // _____

// ============================================
// ============================================
//              SOLUTIONS
// ============================================
// ============================================

/*

// SOLUTION 1: Type Identification
// 1a) typeof: "number"    actual: Number
// 1b) typeof: "string"    actual: String
// 1c) typeof: "boolean"   actual: Boolean
// 1d) typeof: "object"    actual: Null (typeof bug!)
// 1e) typeof: "undefined" actual: Undefined
// 1f) typeof: "symbol"    actual: Symbol
// 1g) typeof: "bigint"    actual: BigInt
// 1h) typeof: "object"    actual: Array
// 1i) typeof: "object"    actual: Object
// 1j) typeof: "function"  actual: Function


// SOLUTION 2: Number Operations
// 2a) false (floating point precision issue)
// 2b) Infinity
// 2c) NaN
// 2d) false (NaN is not equal to anything, including itself)
// 2e) "number"
// 2f) 42
// 2g) NaN
// 2h) NaN (Number() is stricter than parseInt)


// SOLUTION 3: String Manipulation
let str = "JavaScript is awesome!";
console.log(str.length);                    // 3a: 22
console.log(str.toUpperCase());             // 3b: "JAVASCRIPT IS AWESOME!"
console.log(str.includes("awesome"));       // 3c: true
console.log(str.replace("awesome", "amazing")); // 3d: "JavaScript is amazing!"
console.log(str.slice(0, 10));              // 3e: "JavaScript"
console.log(str.split(" "));                // 3f: ["JavaScript", "is", "awesome!"]


// SOLUTION 4: Template Literals
let product = "Laptop";
let price = 999.99;
let inStock = true;
let message = `The ${product} costs $${price} and is ${inStock ? "available" : "out of stock"}`;


// SOLUTION 5: Truthy and Falsy
// 5a) 0           F
// 5b) ""          F
// 5c) "0"         T (non-empty string!)
// 5d) []          T (empty array is truthy!)
// 5e) {}          T (empty object is truthy!)
// 5f) null        F
// 5g) undefined   F
// 5h) NaN         F
// 5i) "false"     T (non-empty string!)
// 5j) -1          T (any non-zero number)


// SOLUTION 6: Null vs Undefined
// 6a) undefined (naturally absent)
// 6b) null (intentionally cleared)
// 6c) null (intentionally "nothing found")
// 6d) undefined (natural state)
// 6e) undefined (property doesn't exist)


// SOLUTION 7: Symbol Practice
const ID = Symbol("id");
const user = {
    name: "John",
    [ID]: 12345
};
console.log(Object.keys(user));  // ["name"] - symbol not included
console.log(user[ID]);           // 12345


// SOLUTION 8: BigInt
// 8a)
let bigNum = 9007199254740993n;

// 8b)
let sum = 100n + 200n;  // 300n

// 8c)
let result = 100n + BigInt(50);  // Convert number to BigInt

// 8d)
console.log(1n == 1);   // true (loose equality)
console.log(1n === 1);  // false (strict equality)


// SOLUTION 9: Reference vs Value
// x = 10 (primitives are copied by value)
// arr1 = [1, 2, 3, 4] (arrays are referenced, both point to same)
// obj1.a = 1 (spread creates shallow copy, obj2 is separate)


// SOLUTION 10: Type Checking Function
function getType(value) {
    if (value === null) return "null";
    if (Array.isArray(value)) return "array";
    return typeof value;
}


// SOLUTION 11: Number Validation
function isValidNumber(value) {
    return typeof value === "number" && 
           !Number.isNaN(value) && 
           Number.isFinite(value);
}


// SOLUTION 12: String Analysis
function analyzeString(str) {
    return {
        length: str.length,
        words: str.trim().split(/\s+/).filter(w => w.length > 0).length,
        hasNumbers: /\d/.test(str),
        hasSpaces: /\s/.test(str)
    };
}


// SOLUTION 13: Truthy/Falsy Converter
function classifyValue(value) {
    const type = value === null ? "null" : typeof value;
    return value ? `truthy: ${type}` : `falsy: ${type}`;
}


// SOLUTION 14: Safe Property Access
// 14a)
let name = data?.user?.profile?.name ?? "Not found";  // "John"

// 14b)
let age = data?.user?.profile?.age ?? "Not found";  // "Not found"

// 14c)
let theme = data?.user?.profile?.settings?.theme ?? "Not found";  // "dark"

// 14d)
let language = data?.user?.preferences?.language ?? "Not found";  // "Not found"


// SOLUTION 15: Type Coercion Puzzle
// 15a) "" (empty string - both arrays become empty strings)
// 15b) "[object Object]" (array becomes "", object becomes "[object Object]")
// 15c) 0 or "[object Object]" (depends on context - {} can be empty block)
// 15d) 2 (true converts to 1)
// 15e) "53" (string concatenation)
// 15f) 2 (string converts to number for subtraction)
// 15g) 1 (null converts to 0)
// 15h) NaN (undefined converts to NaN)

*/
Exercises - JavaScript Tutorial | DeepML