Feather

Debugging JavaScript Code

Summary & Quick Review

2.1 Introduction to Debugging JavaScript Code

Debugging is a critical skill for any JavaScript developer. It involves identifying and resolving issues, or "bugs," in the code to ensure it functions as expected across various environments. Effective debugging can save time and improve the quality of your code.

2.1.1 Common Steps for Debugging JavaScript Code

  • Review Your Code:
    • Look for syntax errors, typos, and logical mistakes.
    • Ensure all braces, brackets, and parentheses are correctly matched.
    • Check variable and function names for consistency.
  • Use Console Outputs:
    • Insert console.log(), console.error(), or console.warn() statements to output variable values and execution flow.
  • Utilize Developer Tools:
    • Use built-in developer tools in modern browsers to set breakpoints and inspect variables.
  • Test in Different Browsers:
    • Test your code in multiple browsers to ensure consistent functionality.
  • Responsive Testing on Various Devices:
    • Check performance on different devices, using emulators and responsive design modes.
  • Use Linting Tools:
    • Tools like ESLint can analyze your code for common issues and enforce coding standards.
  • Seek Help from the Community:
    • Engage with forums like Stack Overflow for solutions and new perspectives.

How/Why This Works

The JavaScript engine interprets your code and logs errors to the console when it encounters issues. By reviewing these messages and setting breakpoints, you can pinpoint exactly where and why your script is failing. Understanding the flow of execution and variable states is key to effective debugging.

Pitfalls / Common Mistakes

  • Over-reliance on alert() or console.log(): Use them judiciously and consider more advanced debugging techniques.
  • Neglecting Cross-Browser Testing: Failing to test across multiple browsers can lead to unexpected issues.
  • Ignoring Error Messages: Always read and understand error messages for valuable debugging information.

Example of Debugging Steps


// A simple function to calculate the average of two numbers
function calculateAverage(num1, num2) {
    console.log("Input numbers: ", num1, num2); // Output the inputs to debug
    var total = num1 + num2;
    var average = total / 2;
    return average;
}

// Test the function with a number and a string
var result = calculateAverage(10, '20'); // This will cause an implicit type conversion
console.log("Result: ", result); // Debugging output

            

In this example, the function calculateAverage takes two inputs. Passing a number and a string causes JavaScript to perform type coercion, which may lead to unexpected results. Debugging outputs help identify this issue.

2.1.2 Using Native and Supplemental Debugging Tools in JavaScript

  • Introduction to Debugging Tools
    • Effective debugging involves understanding code and using the right tools.
    • JavaScript developers have access to various native and supplemental debugging tools.
Native Debugging Tools
  • Browser Developer Tools
    • Console Panel: Logs diagnostic information and allows execution of JavaScript commands.
    • Sources Panel: Set breakpoints, step through code, and inspect variables.
    • Network Panel: Monitor network activity, including API calls and resource loading.
    • Elements Panel: Inspect and modify HTML/CSS in real-time.
  • Enabling/Disabling Display for Debugging
    • Use the `display` CSS property to reveal or hide elements for debugging.
    • Example:
                                  
                                      // Hide an element for debugging
                                      document.getElementById('debug-section').style.display = 'none'; // Hides the element
      
                                      // Later in the code or in response to an event
                                      document.getElementById('debug-section').style.display = 'block'; // Shows the element
                                  
                                  
Supplemental Debugging Tools
  • Linting Tools (e.g., ESLint, JSLint): Analyze code for potential errors and enforce coding standards.
  • Code Formatters (e.g., Prettier): Automatically format code for consistency.
  • Type Checking Tools (e.g., TypeScript): Provide static type-checking to catch type-based errors.
  • Integrated Development Environments (IDEs): Offer advanced debugging features and extensions.
  • Performance and Testing Tools
    • Performance Tools: Analyze runtime performance (e.g., Google Lighthouse).
    • Unit Testing Tools: Frameworks like Jest or Mocha for writing tests.
Importance of Debugging
  • Debugging is essential for developers to identify logic mistakes and compatibility issues.
  • Using the right tools streamlines the debugging process and improves code quality.
Example of Using Debugging Tools
            
                // Using console to debug
                console.log("Debugging: Starting the calculation process.");

                // Dynamically adjusting CSS for debugging
                document.getElementById('debug-section').style.display = 'none'; // Hides the element

                // Perform some operations...

                // Re-display element for further testing
                document.getElementById('debug-section').style.display = 'block'; // Shows the element
                console.log("Debugging: Calculation process completed.");
            
            

2.1.1 Common Steps for Debugging JavaScript Code

2.1.2 Using Native and Supplemental Debugging Tools in JavaScript

JavaScript Control Flow: if Statement

Summary & Quick Review

2.2 Use JavaScript Statements to Control Program Flow

2.2.1 if… Statement

Overview: The if statement is a fundamental control structure in JavaScript that allows developers to execute code conditionally based on the evaluation of an expression. Mastery of the if statement is essential for implementing decision-making logic in your programs.

How the if Statement Works:

The if statement evaluates a condition (an expression that returns a boolean value: true or false). If the condition evaluates to true, the code block within the if statement is executed. If false, the code block is skipped.

Syntax of the if Statement:
if (condition) {
    // code to run if condition is true
}
Examples:
Simple Example:
let temperature = 30;

if (temperature > 25) {
    console.log("It's a hot day!");
}

In this example, if the temperature is greater than 25, the message "It's a hot day!" will be logged to the console.

More Complex Example:
let score = 85;

if (score >= 90) {
    console.log("Grade: A");
} else if (score >= 80) {
    console.log("Grade: B");
} else if (score >= 70) {
    console.log("Grade: C");
} else {
    console.log("Grade: D or F");
}

This program checks the score and logs the corresponding grade based on defined ranges. If the score is 85, it will log "Grade: B".

Key Points to Remember:
  • The condition inside the if statement can be any expression that evaluates to a boolean value.
  • Use comparison operators (e.g., >, <, >=, <=, ===, !==) to form conditions.
  • The if statement can be followed by else and else if clauses to handle multiple conditions.
  • Always use curly braces {} to define the code block for better readability and to avoid errors.
Common Mistakes:
  • Forgetting to use parentheses () around the condition.
  • Using a single equals sign = instead of a double equals == or triple equals === for comparison.
  • Not using curly braces for code blocks, which can lead to unexpected behavior.

2.2.2 while Statement

Overview

The while statement is a fundamental control structure in JavaScript that allows you to execute a block of code repeatedly as long as a specified condition evaluates to true. Mastery of the while loop is essential for scenarios where you need to perform repetitive tasks until a certain condition changes.

How the while Statement Works

A while loop checks the condition before each iteration. If the condition is true, the code block inside the loop is executed. This process continues until the condition evaluates to false. If the condition is false at the first check, the code inside the loop will not execute at all.

Syntax of the while Statement
while (condition) {
            // code runs repeatedly as long as condition is true
        }
Examples
Simple Example
let i = 0;
        while (i < 3) {
            console.log("i is " + i);
            i++;
        }

This example prints the value of i three times (0, 1, and 2) before terminating when i reaches 3.

More Complex Example
let total = 0;
        let count = 1;

        while (count <= 5) {
            total += count; // Add count to total
            count++; // Increment count
        }

        console.log("The total is " + total); // Outputs: The total is 15

This example calculates the sum of the numbers from 1 to 5 and outputs the total.

Key Points to Remember
  • The condition inside the while statement can be any expression that evaluates to a boolean value.
  • Ensure that the loop condition will eventually become false to avoid infinite loops.
  • Variables used in the condition should be properly initialized before the loop and modified during each iteration to ensure the loop can terminate.
Common Pitfalls
  • Infinite Loops: Forgetting to update the loop control variable can create an infinite loop. Always ensure that the condition will eventually evaluate to false.
  • Condition Logic: Be careful with the logic of your condition. Using the wrong comparison operator can lead to unexpected behavior.
Points to Consider
  • Always initialize your loop control variables before entering the loop and ensure they are updated within the loop.
  • You can use the break statement to exit a loop prematurely if a certain condition is met, providing more control over loop execution.

2.2.3 do...while Statement

  • Overview: The do...while statement is a post-condition loop in JavaScript that ensures the code block executes at least once before checking the condition.
  • How it Works: Executes the block of code once, then checks the condition. If true, it continues; if false, it terminates.
  • Syntax:
    do {
                // code block
            } while (condition);
  • Simple Example:
    let i = 0;
    
            do {
                console.log("i is " + i);
                i++;
            } while (i < 3);

    This example prints the values of i (0, 1, and 2) to the console, executing at least once.

  • More Complex Example:
    let userInput;
            let validInput = false;
    
            do {
                userInput = prompt("Please enter a number between 1 and 10:");
                if (userInput >= 1 && userInput <= 10) {
                    validInput = true;
                } else {
                    console.log("Invalid input. Try again.");
                }
            } while (!validInput);
    
            console.log("You entered a valid number: " + userInput);

    This prompts the user until valid input is received, ensuring the prompt is displayed at least once.

Key Points to Remember

  • The do...while loop guarantees at least one execution of the code block.
  • Condition is evaluated after execution, unlike the while loop.
  • Modify the condition within the loop to avoid infinite loops.

Common Pitfalls

  • Infinite Loops: Ensure the condition will eventually evaluate to false.
  • Execution Order: Remember that the code block executes before the condition is checked.

Points to Consider

  • Use Cases: Useful for user input scenarios or when a block of code must run at least once.
  • Control of Loop: Always update the loop control variable to prevent infinite execution.

2.2.4 for Statement

  • Overview: The for statement is a commonly used loop in JavaScript, ideal for iterating over a range of values, especially arrays.
  • How it Works:
    • Initialization: Define and initialize the loop variable.
    • Condition: Evaluated before each iteration; the loop continues while true.
    • Increment/Decrement: Updates the loop variable after each iteration.
  • Syntax:
    for (initialization; condition; increment) {
            // code block to be executed
        }
  • Examples:
    • Simple Example:
      for (let i = 0; i < 5; i++) {
              console.log("Iteration: " + i);
          }

      This prints "Iteration: 0" through "Iteration: 4".

    • More Complex Example:
      let sum = 0;
          for (let j = 1; j <= 10; j++) {
              sum += j; // Add j to sum
          }
          console.log("The sum of numbers from 1 to 10 is: " + sum);

      This calculates the sum of numbers from 1 to 10.

  • Key Points:
    • Ideal for known iteration counts.
    • All components are part of the loop declaration.
    • Flexible expressions can be used in all sections.
  • Common Pitfalls:
    • Off-by-One Errors: Ensure correct loop conditions.
    • Infinite Loops: Update loop variables correctly to avoid infinite loops.
  • Points to Consider:
    • Nested Loops: Can handle multi-dimensional data structures.
    • Loop Control Statements: Use break to exit or continue to skip iterations.
    • Iterating Over Arrays: Commonly used to access array elements by index.

2.2.5 forEach Method

  • Overview: The forEach method executes a specified function on each item in an array, making it useful for iterating without a loop counter.
  • How it Works: Executes the callback function for each array element in order. It does not return a new array.
  • Syntax:
    array.forEach((element, index, array) => {
            // code block
        });
  • Parameters:
    • element: Current element being processed.
    • index (optional): Index of the current element.
    • array (optional): The array forEach was called upon.
  • Simple Example:
    let fruits = ["apple", "banana", "cherry"];
        fruits.forEach((fruit) => {
            console.log(fruit);
        });
  • More Complex Example:
    let numbers = [1, 2, 3, 4, 5];
        let sum = 0;
    
        numbers.forEach((number, index) => {
            sum += number;
            console.log("Index " + index + ": " + number);
        });
    
        console.log("Total sum: " + sum); // Outputs: Total sum: 15
  • Key Points:
    • Ideal for executing functions on each element without manual index management.
    • Useful for operations that do not require a return value.
    • Callback functions can be defined using arrow functions for concise syntax.
  • Common Pitfalls:
    • No break or continue statements can be used.
    • Performance may be less optimal for large arrays compared to traditional loops.
  • Points to Consider:
    • Be mindful of the scope of this when using forEach.
    • Can be used with other array methods for complex operations.

2.2.6 Break and Continue Statements

  • Overview: The break and continue statements are control flow statements used to alter the execution of loops in JavaScript.
  • How They Work:
    • break: Exits the nearest enclosing loop or switch statement.
    • continue: Skips the current iteration and proceeds to the next one.

Syntax and Usage

Using break:
        
        for (let i = 0; i < 10; i++) {
        if (i === 5) {
            break; // Exit the loop when i is 5
        }
        console.log(i); // Outputs: 0, 1, 2, 3, 4
        }
        
            

In this example, the loop terminates when i equals 5, logging numbers 0 through 4.

Using continue:
        
        for (let j = 0; j < 10; j++) {
        if (j % 2 === 0) {
            continue; // Skip the rest of the loop for even numbers
        }
        console.log(j); // Outputs: 1, 3, 5, 7, 9
        }
        
            

This example skips even numbers, logging only the odd numbers from 0 to 9.

More Complex Example with break:
        
        let numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
        for (let k = 0; k < numbers.length; k++) {
        if (numbers[k] > 5) {
            break; // Exit the loop when a number greater than 5 is found
        }
        console.log(numbers[k]); // Outputs: 1, 2, 3, 4, 5
        }
        
            

The loop terminates upon encountering a number greater than 5.

More Complex Example with continue:
        
        let total = 0;
        for (let m = 1; m <= 10; m++) {
        if (m % 2 === 0) {
            continue; // Skip even numbers
        }
        total += m; // Add odd numbers to total
        }
        console.log("Total of odd numbers from 1 to 10: " + total); // Outputs: Total of odd numbers from 1 to 10: 25
        
            

This example calculates the sum of odd numbers from 1 to 10 while skipping even numbers.

Points to Consider:

  • Where to Use: Both break and continue can be used in any type of loop, including for, while, and do...while loops.
  • Labeled Statements: You can use labeled statements with break and continue to control the flow of outer loops in nested loops.
Example of Labeled Statements:
        
        outerLoop: for (let a = 0; a < 3; a++) {
        for (let b = 0; b < 3; b++) {
            if (a === 1 && b === 1) {
            break outerLoop; // Exit both loops when a is 1 and b is 1
            }
            console.log(`a: ${a}, b: ${b}`);
        }
        }
        
            

In this example, the labeled break statement exits both the inner and outer loops when a is 1 and b is 1.

2.2.7 switch Statement

  • Overview: The switch statement is a control structure in JavaScript that allows you to perform different actions based on different conditions, serving as an alternative to multiple if statements.
  • How it Works: The switch statement evaluates an expression and compares it against multiple case values. When a match is found, the associated code is executed. A break statement prevents fall-through to the next case.
  • Syntax:
    
            switch (expression) {
                case value1:
                    // code for value1
                    break;
                case value2:
                    // code for value2
                    break;
                default:
                    // code if no match
            }
                        
  • Examples:
    • Simple Example:
      
              let day = 3;
              switch (day) {
                  case 1: console.log("Monday"); break;
                  case 2: console.log("Tuesday"); break;
                  case 3: console.log("Wednesday"); break;
                  case 4: console.log("Thursday"); break;
                  case 5: console.log("Friday"); break;
                  case 6: console.log("Saturday"); break;
                  case 7: console.log("Sunday"); break;
                  default: console.log("Invalid day");
              }
                                  
      *Outputs "Wednesday".*
    • More Complex Example:
      
              let fruit = "banana";
              switch (fruit) {
                  case "apple": console.log("You chose an apple."); break;
                  case "banana": console.log("You chose a banana."); break;
                  case "cherry": console.log("You chose a cherry."); break;
                  default: console.log("Unknown fruit.");
              }
                                  
      *Outputs "You chose a banana."*
  • Key Points:
    • More readable than multiple if/else blocks.
    • Each case should end with a break to prevent fall-through.
    • default case is optional for handling unexpected values.
  • Common Pitfalls:
    • Fall-through behavior if break is omitted.
    • Strict comparison (===) requires matching types.
  • Additional Considerations:
    • Expressions can include variables, function calls, or arithmetic operations.
    • Group multiple cases together for shared code execution:
      
              switch (value) {
                  case 1:
                  case 2:
                  case 3:
                      console.log("Value is between 1 and 3");
                      break;
                  default:
                      console.log("Value is outside the range");
              }
                                  

2.2.1 if… Statement

2.2.2 while Statement

2.2.3 do...while Statement

2.2.4 for Statement

2.2.5 forEach Method

2.2.6 Break and Continue Statements

2.2.7 switch Statement

Study Guide: JavaScript Document Object Model (DOM)

Summary & Quick Review

2.3.1 Manipulating the DOM with JavaScript

  • Understanding the DOM:
    • The DOM is a tree-like structure representing the webpage.
    • JavaScript can access and modify nodes dynamically.
  • Common DOM Manipulation Techniques:
    • Selecting Elements:
      • document.getElementById('elementId')
      • document.getElementsByClassName('className')
      • document.getElementsByTagName('tagName')
      • document.querySelector('selector')
      • document.querySelectorAll('selector')
    • Manipulating Elements:
      • element.innerHTML = 'new content';
      • element.textContent = 'new text';
      • element.setAttribute('attributeName', 'value');
      • element.style.property = 'value';
    • Creating and Appending Elements:
      • var newElement = document.createElement('tagName');
      • parentElement.appendChild(newElement);
    • Event Handling:
      • element.addEventListener('event', function() { /* code */ });

Example of DOM Manipulation

                
                    // Example code for DOM manipulation
                    let div = document.getElementById("myDiv");
                    let button = document.getElementById("changeTextButton");

                    button.addEventListener('click', function() {
                        div.innerHTML = "Text changed on button click!";
                    });
                
            

Best Practices for DOM Manipulation

  • Minimize DOM Access
  • Batch DOM Updates
  • Use Event Delegation
  • Avoid Inline Styles
  • Validate User Input
  • Use const and let for variable declarations

Conclusion

Mastering DOM manipulation is essential for creating dynamic web applications. Practice these techniques to enhance your skills.

2.3.2 The Window Object

Introduction

The window object represents the browser window and provides methods and properties for interacting with the browser environment.

Key Properties:

  • window.innerHeight: Height of the content area.
  • window.innerWidth: Width of the content area.
  • window.location: Current URL information.
  • window.localStorage: Stores key-value pairs.

Key Methods:

  • window.alert(): Displays an alert dialog.
  • window.confirm(): Displays a confirmation dialog.
  • window.prompt(): Prompts for user input.

Examples

Alert Example:

window.onload = function() { window.alert("Welcome!"); };

Using localStorage:


        document.getElementById("storeNameButton").addEventListener("click", function() {
            let name = window.prompt("Enter your name:");
            if (name) window.localStorage.setItem("userName", name);
        });
            

Best Practices

  • Use const and let for variables.
  • Avoid excessive alerts; use custom dialogs instead.
  • Check for storage availability before use.

Resources

Conclusion

Mastering the window object is crucial for creating interactive web applications. Practice using its properties and methods to enhance your JavaScript skills.

Study Guide: The Document Object

2.3.3: The Document Object

The document object represents the entire HTML document in the DOM (Document Object Model). It provides properties and methods for accessing and manipulating elements and other content within the document, allowing developers to create dynamic and interactive web pages.

Common Properties and Methods of the Document Object

Properties:
  • document.body: Accesses the <body> element.
  • document.title: Gets or sets the document's title.
  • document.URL: Returns the current document's URL.
  • document.head: Accesses the <head> element.
Methods:
  • document.getElementById('id'): Returns the element with the specified ID.
  • document.getElementsByClassName('className'): Returns elements with the specified class name.
  • document.getElementsByTagName('tagName'): Returns elements with the specified tag name.
  • document.querySelector('selector'): Returns the first matching element for a CSS selector.
  • document.querySelectorAll('selector'): Returns all matching elements for a CSS selector.
  • document.createElement('tagName'): Creates a new element with the specified tag name.

Example Using the Document Object

Simple Example: Changing the Document Title
                
                    // Change the title of the document when the page loads
                    window.onload = function() {
                        document.title = "Welcome to the CIW JavaScript Specialist Exam!";
                    };
                
            
More Complex Example: Creating and Manipulating Elements
                
                    <!DOCTYPE html>
                    <html lang="en">
                    <head>
                        <meta charset="UTF-8">
                        <meta name="viewport" content="width=device-width, initial-scale=1.0">
                        <title>Document Object Example</title>
                    </head>
                    <body>
                        <h1>Document Object Example</h1>
                        <button id="addElementButton">Add New Element</button>
                        <div id="container"></div>

                        <script>
                            // Function to add a new paragraph to the container
                            document.getElementById("addElementButton").addEventListener("click", function() {
                                // Create a new paragraph element
                                var newParagraph = document.createElement("p");
                                newParagraph.textContent = "This is a new paragraph added to the document.";
                                
                                // Append the new paragraph to the container
                                document.getElementById("container").appendChild(newParagraph);
                            });
                        </script>
                    </body>
                    </html>
                
            

Best Practices for Using the Document Object

  • Use const and let: Prefer const for constants and let for variables that may change to maintain clean and predictable code.
  • Minimize DOM Access: Accessing the DOM can be slow, so minimize the number of times you access it. Store references to elements in variables if you need to manipulate them multiple times.
  • Batch DOM Updates: When making multiple changes to the DOM, consider batching them together. Create elements in memory and append them to the DOM in one operation to improve performance.
  • Use DOMContentLoaded: To ensure your scripts run after the DOM is fully loaded, use the DOMContentLoaded event instead of window.onload, as it fires earlier.
  • Validate User Input: Always validate user input before manipulating the DOM to prevent errors and ensure a good user experience.

Additional Resources for Study

  • MDN Web Docs: Comprehensive documentation on the document object and its properties/methods.
  • JavaScript.info: A great resource for learning JavaScript, including sections on the document object and its functionalities.
  • W3Schools: Offers tutorials and references on web development topics, including JavaScript and the document object.
  • YouTube Tutorials: Look for video tutorials on the Document Object and its usage in JavaScript.

2.3.4: The Image Object (Image Rollover Example)

Introduction to the Image Object in the DOM

The Image object in the DOM represents an HTML <img> element. It allows developers to create new image elements dynamically, manipulate their properties, and handle events associated with images, enhancing interactivity on web pages.

Creating and Manipulating Image Elements

Creating an Image Element

You can create an image element dynamically using JavaScript. Here’s a simple example:

                
                    // Create a new image element
                    let newImage = document.createElement("img");
                    newImage.src = "default_image.jpg"; // Set the source
                    newImage.alt = "A description of the image"; // Set alt text
                    newImage.width = 300; // Set width
                    newImage.height = 200; // Set height

                    // Append the image to the body
                    document.body.appendChild(newImage);
                
            

Setting Image Properties

  • img.src: Sets or returns the source URL of the image.
  • img.alt: Sets or returns the alternative text for the image.
  • img.width and img.height: Sets or returns the dimensions of the image in pixels.

Image Rollover Creation

The image rollover effect changes the src attribute of an image on mouseover and mouseout events, creating an interactive experience.

Example: Basic Image Rollover

                
                    <!DOCTYPE html>
                    <html lang="en">
                    <head>
                        <meta charset="UTF-8">
                        <meta name="viewport" content="width=device-width, initial-scale=1.0">
                        <title>Image Rollover Example</title>
                    </head>
                    <body>
                        <h1>Image Rollover Example</h1>
                        <img id="myImg" src="default_image.jpg" alt="Default Image" width="300" height="200">

                        <script>
                            let img = document.getElementById("myImg");
                            img.onmouseover = function() {
                                img.src = "hover_image.jpg"; // Change to hover image
                            };
                            img.onmouseout = function() {
                                img.src = "default_image.jpg"; // Change back to default image
                            };
                        </script>
                    </body>
                    </html>
                
            

Example: Multiple Image Rollover

                
                    <!DOCTYPE html>
                    <html lang="en">
                    <head>
                        <meta charset="UTF-8">
                        <meta name="viewport" content="width=device-width, initial-scale=1.0">
                        <title>Multiple Image Rollover Example</title>
                    </head>
                    <body>
                        <h1>Multiple Image Rollover Example</h1>
                        <div id="imageContainer">
                            <img id="img1"
                            src="default_image1.jpg" alt="Image 1" width="300" height="200">
                            <img id="img2" src="default_image2.jpg" alt="Image 2" width="300" height="200">
                        </div>

                        <script>
                            function setupImageRollover(imgId, hoverSrc, defaultSrc) {
                                let img = document.getElementById(imgId);
                                img.onmouseover = function() {
                                    img.src = hoverSrc; // Change to hover image
                                };
                                img.onmouseout = function() {
                                    img.src = defaultSrc; // Change back to default image
                                };
                            }

                            // Set up rollover for both images
                            setupImageRollover("img1", "hover_image1.jpg", "default_image1.jpg");
                            setupImageRollover("img2", "hover_image2.jpg", "default_image2.jpg");
                        </script>
                    </body>
                    </html>
                
            

Best Practices for Using the Image Object

  • Use Descriptive Alt Text: Always provide meaningful alternative text for images using the alt attribute to improve accessibility.
  • Optimize Image Sizes: Use appropriately sized images to enhance loading times and performance.
  • Preload Images: Preload images that will be displayed soon to improve user experience.
                        
                            let preloadImage = new Image();
                            preloadImage.src = "hover_image.jpg"; // Preload the hover image
                        
                    
  • Use CSS for Hover Effects: For simple hover effects, consider using CSS instead of JavaScript for better performance.
  • Handle Image Load Errors: Implement error handling for images that fail to load using the onerror event.
  • Consider Lazy Loading: For pages with many images, implement lazy loading to improve performance.

Additional Resources for Study

Conclusion

Understanding how to manipulate the Image object in JavaScript is essential for creating interactive and visually appealing web applications. By mastering image rollovers and other image manipulations, you can enhance user experience and engagement on your web pages. Practice these concepts through hands-on coding and experimentation to solidify your understanding.

2.3.5 The History Object

  • Introduction: The history object represents the user's browsing history for the current window, allowing navigation and manipulation of the history stack.

Common Methods and Properties

  • Properties:
    • history.length: Number of URLs in the history list.
    • history.state: State object at the top of the history stack.
  • Methods:
    • history.back(): Moves back one page.
    • history.forward(): Moves forward one page.
    • history.go(n): Moves to a specific page in history.

Example Using the History Object

Simple Example: Navigating Back and Forward

                
                    <!DOCTYPE html>
                    <html lang="en">
                    <head>
                        <meta charset="UTF-8">
                        <meta name="viewport" content="width=device-width, initial-scale=1.0">
                        <title>History Object Example</title>
                    </head>
                    <body>
                        <h1>History Object Example</h1>
                        <button id="backButton">Go Back</button>
                        <button id="forwardButton">Go Forward</button>
                        <p id="historyLength"></p>

                        <script>
                            document.getElementById("historyLength").textContent = "History Length: " + history.length;
                            document.getElementById("backButton").onclick = function() { history.back(); };
                            document.getElementById("forwardButton").onclick = function() { history.forward(); };
                        </script>
                    </body>
                    </html>
                
            

More Complex Example: Custom Navigation

                
                    <!DOCTYPE html>
                    <html lang="en">
                    <head>
                        <meta charset="UTF-8">
                        <meta name="viewport" content="width=device-width, initial-scale=1.0">
                        <title>Custom History Navigation</title>
                    </head>
                    <body>
                        <h1>Custom History Navigation</h1>
                        <button id="goBackButton">Go Back</button>
                        <button id="goForwardButton">Go Forward</button>
                        <button id="goToPage2Button">Go to Page 2</button>
                        <p id="currentState"></p>

                        <script>
                            function updateState() {
                                document.getElementById("currentState").textContent = "Current State: " + JSON.stringify(history.state);
                            }
                            document.getElementById("goBackButton").onclick = function() { history.back(); updateState(); };
                            document.getElementById("goForwardButton").onclick = function() { history.forward(); updateState(); };
                            document.getElementById("goToPage2Button").onclick = function() {
                                history.pushState({ page: 2 }, "Page 2", "page2.html");
                                updateState();
                                document.body.innerHTML += "<p>You are now on Page 2!</p>";
                            };
                            updateState();
                        </script>
                    </body>
                    </html>
                
            

Best Practices for Using the History Object

  • Use pushState and replaceState to manage history effectively without page reloads.
  • Handle state changes with the popstate event to update the UI based on the current state.
                            
                                window.onpopstate = function(event) {
                                    if (event.state) {
                                        document.getElementById("currentState").textContent = "Current State: " + JSON.stringify(event.state);
                                    }
                                };
                            
                        
  • Avoid overusing history navigation to prevent user confusion.
  • Test your implementation across different browsers for consistent behavior.
  • Use meaningful state objects with pushState and replaceState for better state management.

Additional Resources for Study

Conclusion

Understanding the History object is essential for creating dynamic web applications that provide a seamless user experience. By mastering the methods and properties of the History object, you can implement effective navigation controls and manage the user's browsing history within your application. Practice these concepts through hands-on coding and experimentation to solidify your understanding, and familiarize yourself with best practices to ensure user-friendly and efficient history management.

2.3.6 The Location Object

Introduction to the Location Object: The location object in the DOM represents the current URL of the document. It provides information about the URL and allows you to change parts of the URL, effectively navigating to a new page or reloading the current page with different parameters.

Common Properties and Methods of the Location Object
  • Properties:
    • location.href: Returns the entire URL of the current page.
    • location.host: Returns the hostname and port number of the current URL.
    • location.pathname: Returns the path and filename of the current URL.
    • location.search: Returns the query string of the current URL.
    • location.hash: Returns the anchor part of the URL.
  • Methods:
    • location.assign('url'): Loads a new document at the specified URL.
    • location.replace('url'): Replaces the current document with a new one.
    • location.reload(): Reloads the current document.
Example Using the Location Object

Simple Example: Displaying Current URL Information

                
                    <!DOCTYPE html>
                    <html lang="en">
                    <head>
                        <meta charset="UTF-8">
                        <meta name="viewport" content="width=device-width, initial-scale=1.0">
                        <title>Location Object Example</title>
                    </head>
                    <body>
                        <h1>Location Object Example</h1>
                        <p id="urlInfo"></p>
                        <button id="reloadButton">Reload Page</button>

                        <script>
                            document.getElementById("urlInfo").textContent = "Current URL: " + location.href;
                            document.getElementById("reloadButton").onclick = function() {
                                location.reload();
                            };
                        </script>
                    </body>
                    </html>
                
            

More Complex Example: Changing URL Parameters

                
                    <!DOCTYPE html>
                    <html lang="en">
                    <head>
                        <meta charset="UTF-8">
                        <meta name="viewport" content="width=device-width, initial-scale=1.0">
                        <title>Change URL Parameters Example</title>
                    </head>
                    <body>
                        <h1>Change URL Parameters Example</h1>
                        <p id="currentParams"></p>
                        <button id="changeParamsButton">Change URL Parameters</button>

                        <script>
                            function displayCurrentParams() {
                                document.getElementById("currentParams").textContent = "Current Query Parameters: " + location.search;
                            }
                            document.getElementById("changeParamsButton").onclick = function() {
                                let params = new URLSearchParams(location.search);
                                params.set('newParam', 'value'); // Add or update a parameter
                                location.search = params.toString(); // Update the URL with new parameters
                            };

                            // Initial display of current parameters
                            displayCurrentParams();
                        </script>
                    </body>
                    </html>
                
            
Best Practices for Using the Location Object
  • Use location.replace() for navigation to avoid creating history entries.
  • Validate URL changes to prevent broken links or errors.
  • Utilize URLSearchParams for easier manipulation of query strings.
  • Be cautious with location.reload() to avoid disrupting user experience.
  • Handle URL changes gracefully in the user interface.
  • Test across different browsers for consistent behavior.
Additional Resources for Study
Conclusion

Understanding the Location object is essential for managing navigation and URL manipulation in web applications. By mastering its properties and methods, you can create dynamic and user-friendly experiences that allow users to navigate seamlessly through your application. Practice these concepts through hands-on coding and experimentation to solidify your understanding.

2.3.7 The Navigator Object

  • The navigator object provides information about the web browser and its capabilities.
  • Essential for developing cross-browser compatible web applications.
  • Key features include:
    • Detecting browser type and version.
    • Providing user preferences and settings.
    • Helping in feature detection for better user experience.

Common Properties of the Navigator Object

  • navigator.userAgent: Returns a string with browser information.
  • navigator.language: Returns the user's preferred language.
  • navigator.appName: Returns the name of the browser.
  • navigator.appVersion: Returns the version of the browser.
  • navigator.platform: Indicates the platform (operating system) of the browser.

Examples Using the Navigator Object

  • Simple Example: Detecting the Browser Type
  •                 
                        // Log the user agent
                        console.log("User Agent: " + navigator.userAgent);
                    
                    
  • More Complex Example: Customizing Content Based on Language
  •                 
                        // Customize content based on user's language
                        const userLang = navigator.language || navigator.userLanguage; // For older IE
                        console.log("User's Preferred Language: " + userLang);
    
                        if (userLang.startsWith('es')) {
                            document.body.innerHTML = "

    Bienvenido a nuestro sitio web!

    "; // Spanish } else { document.body.innerHTML = "

    Welcome to our website!

    "; // Default to English }

Additional Considerations

  • Browser Compatibility: Test your code in multiple environments.
  • Privacy Concerns: Some users may limit navigator information.
  • Feature Detection: Use libraries like Modernizr for better compatibility.

Conclusion

  • Understanding the navigator object is crucial for JavaScript developers.
  • This knowledge is essential for creating applications that function seamlessly across various browsers.

2.3.1 Manipulating the DOM with JavaScript

2.3.2 The Window Object

2.3.3 The Document Object

2.3.4: The Image Object

2.3.5 The History Object

2.3.6 The Location Object

2.3.7 The Navigator Object

Study Guide: Section 2.4 - Using JavaScript Language Objects

Summary & Quick Review

2.4.1 The String Object

  • Creating Strings:
    • Primitive string: let str = "Hello";
    • String object: let strObj = new String("Hello");

    Note: Use string literals for simplicity and performance.

  • Introduction to the String Object: Represents a sequence of characters with methods for manipulation and formatting, useful for validating user input.

Common Methods of the String Object

  • charAt(index) - Returns the character at the specified index.
    let str = "Hello"; console.log(str.charAt(1)); // Output: "e"
  • indexOf(searchValue [, fromIndex]) - Returns the index of the first occurrence of a specified value.
    let str = "Hello, world!"; console.log(str.indexOf("o")); // Output: 4
  • lastIndexOf(searchValue [, fromIndex]) - Returns the index of the last occurrence of a specified value.
    let str = "Hello, world!"; console.log(str.lastIndexOf("o")); // Output: 8
  • startsWith(searchString [, position]) - Checks if the string starts with the specified substring.
    let str = "Hello, world!"; console.log(str.startsWith("Hello")); // Output: true
  • endsWith(searchString [, length]) - Checks if the string ends with the specified substring.
    let str = "Hello, world!"; console.log(str.endsWith("world!")); // Output: true
  • includes(searchString [, position]) - Checks if the string contains the specified substring.
    let str = "Hello, world!"; console.log(str.includes("world")); // Output: true

Examples Using the String Object

  • Simple Example:
    let userInput = "JavaScript is fun!"; if (userInput.includes("fun")) { console.log("The input contains the word 'fun'."); }
  • More Complex Example:
    let userInput = "Please enter your email: example@example.com"; let emailPattern = /^[^\s@]+@[^\s@]+\.[^\s@]+$/; if (userInput.includes("@") && emailPattern.test(userInput)) { console.log("Valid email format."); } else { console.log("Invalid email format."); }

Summary

Understanding the String object and its methods is crucial for validating and processing user input in JavaScript. Familiarize yourself with these methods and practice using them in various scenarios to enhance your skills for the exam.

2.4.2 Evaluating Strings

Strings in JavaScript can be evaluated and manipulated using various methods and properties. Understanding these methods is essential for effectively working with string data.

Common String Methods and Properties
  • .length - Returns the number of characters in a string.
    let str = "Hello, world!";
            console.log(str.length); // Output: 13
  • .indexOf(searchValue [, startIndex]) - Returns the index of the first occurrence of a specified value, or -1 if not found.
    let str = "Hello, world!";
            console.log(str.indexOf("o")); // Output: 4
  • .lastIndexOf(searchValue [, startIndex]) - Returns the index of the last occurrence of a specified value, or -1 if not found.
    let str = "Hello, world! Hello again!";
            console.log(str.lastIndexOf("Hello")); // Output: 20
  • .substring(startIndex [, endIndex]) - Returns a new string containing characters from startIndex to endIndex (excluding endIndex).
    let str = "Hello, world!";
            console.log(str.substring(0, 5)); // Output: "Hello"
  • .charAt(index) - Returns the character at the specified index.
    let str = "Hello, world!";
            console.log(str.charAt(0)); // Output: "H"
Example Usage of String Evaluation Methods
Simple Example
let str = "JavaScript is fun!";
        console.log("Length of string:", str.length); // Output: Length of string: 20
        console.log("Index of 'fun':", str.indexOf("fun")); // Output: Index of 'fun': 15
More Complex Example
let str = "The quick brown fox jumps over the lazy dog.";
        let searchWord = "fox";

        console.log("Length of string:", str.length); // Output: 43
        let index = str.indexOf(searchWord);
        if (index !== -1) {
            console.log(`The word '${searchWord}' is found at index:`, index); // Output: The word 'fox' is found at index: 16
        } else {
            console.log(`The word '${searchWord}' is not found.`);
        }
        let extracted = str.substring(index, index + searchWord.length);
        console.log("Extracted substring:", extracted); // Output: Extracted substring: fox
        console.log("Last character of the string:", str.charAt(str.length - 1)); // Output: Last character of the string: .

2.4.3 Regular Expressions and the RegExp Object

  • Introduction to Regular Expressions (RegExp)
    • Regular expressions (regex) are patterns used to match character combinations in strings.
    • In JavaScript, regex are objects of the RegExp class and can be defined using forward slashes (e.g., /pattern/).
  • Common Methods of the RegExp Object
    • test(string): Tests for a match in a string. Returns true if a match is found; otherwise, false.
      
              let pattern = /hello/i; // "i" for case-insensitive
              let result = pattern.test("Hello world");
              console.log(result); // Output: true
                                  
    • exec(string): Executes a search for a match in a string. Returns an array of information about the match or null if no match is found.
      
              let pattern = /hello/i;
              let result = pattern.exec("Hello world");
              console.log(result); // Output: [ 'Hello', index: 0, input: 'Hello world', groups: undefined ]
                                  
  • Common Regular Expression Patterns
    • Literal Characters: Characters that match themselves. Example: /hello/ matches "hello".
    • Character Classes: Match any one of a set of characters. Example: /[aeiou]/ matches any vowel.
    • Quantifiers: Specify the number of occurrences. Example: /a+/ matches one or more 'a' characters.
    • Anchors: Specify the position in the string. Example: /^hello/ matches "hello" at the start of the string.
  • Example Usage of Regular Expressions
    • Simple Example
      
              let emailPattern = /^[^\s@]+@[^\s@]+\.[^\s@]+$/; // Simple regex for email validation
              let email = "example@example.com";
      
              if (emailPattern.test(email)) {
                  console.log("Valid email format."); // Output: Valid email format.
              } else {
                  console.log("Invalid email format.");
                                  
    • More Complex Example
      
              let phonePattern = /^\(\d{3}\) \d{3}-\d{4}$/; // Matches phone numbers in the format (123) 456-7890
              let phoneNumber = "(123) 456-7890";
      
              if (phonePattern.test(phoneNumber)) {
                  console.log("Valid phone number format."); // Output: Valid phone number format.
              } else {
                  console.log("Invalid phone number format.");
              }
      
              // Using exec to extract information
              let text = "My email is example@example.com and my phone number is (123) 456-7890.";
              let emailMatch = emailPattern.exec(text);
              let phoneMatch = phonePattern.exec(text);
      
              if (emailMatch) {
                  console.log("Extracted email:", emailMatch[0]); // Output: Extracted email: example@example.com
              }
      
              if (phoneMatch) {
                  console.log("Extracted phone number:", phoneMatch[0]); // Output: Extracted phone number: (123) 456-7890
                                  

2.4.4 The Array Object

  • Introduction to the Array Object
    • The Array object in JavaScript is used to store multiple values in a single variable.
    • It provides various methods for manipulating arrays, leading to more efficient and readable code.
  • Creating Arrays
    • Using array literal syntax:
      let fruits = ["apple", "banana", "cherry"];
    • Using the Array constructor:
      let vegetables = new Array("carrot", "broccoli", "spinach");
  • Common Methods of the Array Object
    • .push(element1, element2, ...): Adds elements to the end of an array.
      
              let numbers = [1, 2, 3];
              numbers.push(4, 5);
              console.log(numbers); // Output: [1, 2, 3, 4, 5]
                                  
    • .pop(): Removes the last element from an array.
      
              let numbers = [1, 2, 3, 4];
              let lastElement = numbers.pop();
              console.log(lastElement); // Output: 4
              console.log(numbers); // Output: [1, 2, 3]
                                  
    • .splice(startIndex, deleteCount, element1, ...): Adds or removes elements at a specified index.
      
              let colors = ["red", "green", "blue"];
              colors.splice(1, 1, "yellow");
              console.log(colors); // Output: ["red", "yellow", "blue"]
                                  
    • .forEach(callback): Executes a function for each array element.
      
              let numbers = [1, 2, 3, 4];
              numbers.forEach(function(num) {
                  console.log(num * 2); // Output: 2, 4, 6, 8
              });
                                  
  • Example Using the Array Object
    • Simple Example
      
              let fruits = ["apple", "banana", "cherry"];
              fruits.push("date");
              console.log(fruits); // Output: ["apple", "banana", "cherry", "date"]
                                  
    • More Complex Example
      
              let students = [
                  { name: "Alice", score: 85 },
                  { name: "Bob", score: 92 },
                  { name: "Charlie", score: 78 }
              ];
      
              students.forEach(function(student) {
                  console.log(`${student.name}: ${student.score}`);
              });
      
              students.push({ name: "David", score: 88 });
              console.log(students);
      
              let removedStudent = students.pop();
              console.log(`Removed student: ${removedStudent.name}`);
      
              students.splice(1, 1, { name: "Eve", score: 95 });
              console.log(students);
                                  

2.4.5 The map() Method

  • Introduction to the map() Method
    • The map() method is used to iterate over an array and transform each element based on a callback function.
    • It returns a new array containing the transformed elements, without mutating the original array.
  • Syntax of the map() Method
    
            let newArray = array.map((currentValue, index, array) => {
                // Return the new value for the new array
            });
                        
    • currentValue: The current element being processed in the array.
    • index (Optional): The index of the current element being processed.
    • array (Optional): The array map() was called upon.
  • Common Usage of the map() Method
    • Transforming Array Elements
      
              let numbers = [1, 2, 3, 4];
              let doubled = numbers.map(function(num) {
                  return num * 2;
              });
              console.log(doubled); // Output: [2, 4, 6, 8]
                                  
    • Converting Data Format
      
              let students = [
                  { name: "Alice", score: 85 },
                  { name: "Bob", score: 92 },
                  { name: "Charlie", score: 78 }
              ];
              let names = students.map(function(student) {
                  return student.name;
              });
              console.log(names); // Output: ["Alice", "Bob", "Charlie"]
                                  
    • Using Arrow Functions (ES6+)
      
              let numbers = [1, 2, 3, 4];
              let squared = numbers.map(num => num ** 2);
              console.log(squared); // Output: [1, 4, 9, 16]
                                  
  • Example Usage of the map() Method
    • Simple Example
      
              let fruits = ["apple", "banana", "cherry"];
              let uppercasedFruits = fruits.map(fruit => fruit.toUpperCase());
              console.log(uppercasedFruits); // Output: ["APPLE", "BANANA", "CHERRY"]
                                  
    • More Complex Example
      
              let products = [
                  { name: "Laptop", price: 999 },
                  { name: "Phone", price: 499 },
                  { name: "Tablet", price: 299 }
              ];
      
              let discountedPrices = products.map(product => {
                  return {
                      name: product.name,
                      discountedPrice: product.price * 0.9 // 10% discount
                  };
              });
      
              console.log(discountedPrices);
              /*
              Output:
              [
                  { name: "Laptop", discountedPrice: 899.1 },
                  { name: "Phone", discountedPrice: 449.1 },
                  { name: "Tablet", discountedPrice: 269.1 }
              ]
                                  

2.4.6 The Date and Math Objects

  • Introduction to the Date Object
    • The Date object is used for working with dates and times, providing methods for creating, formatting, and manipulating dates.
  • Common Methods of the Date Object
    • new Date() Constructor
      let now = new Date();

      Output: Current date and time

    • getDate(): Returns the day of the month (1-31).
      let date = new Date("2025-07-06");
              console.log(date.getDate()); // Output: 6
    • getMonth(): Returns the month (0-11).
      let date = new Date("2025-07-06");
              console.log(date.getMonth()); // Output: 6 (July)
    • getFullYear(): Returns the four-digit year.
      let date = new Date("2025-07-06");
              console.log(date.getFullYear()); // Output: 2025
    • getDay(): Returns the day of the week (0-6).
      let date = new Date("2025-07-06");
              console.log(date.getDay()); // Output: 0 (Sunday)
  • Introduction to the Math Object
    • The Math object provides mathematical constants and functions for performing mathematical operations.
  • Common Methods of the Math Object
    • Math.PI: Represents the ratio of the circumference of a circle to its diameter.
      console.log(Math.PI); // Output: 3.141592653589793
    • Math.round(): Rounds a number to the nearest integer.
      console.log(Math.round(4.6)); // Output: 5
    • Math.floor(): Rounds a number down to the nearest integer.
      console.log(Math.floor(4.9)); // Output: 4
    • Math.random(): Returns a random number between 0 (inclusive) and 1 (exclusive).
      console.log(Math.random()); // Output: Random decimal between 0 and 1
  • Example Using the Date and Math Objects
    • Simple Example
      
              let now = new Date();
              console.log("Current Date and Time:", now);
              console.log("Current Year:", now.getFullYear());
              console.log("Current Month (0-11):", now.getMonth());
              console.log("Current Day of the Month:", now.getDate());
                                  
    • More Complex Example
      
              // Generate a random date within a specific range
              function getRandomDate(start, end) {
                  return new Date(start.getTime() + Math.random() * (end.getTime() - start.getTime()));
              }
      
              let startDate = new Date("2025-01-01");
              let endDate = new Date("2025-12-31");
              let randomDate = getRandomDate(startDate, endDate);
      
              console.log("Random Date:", randomDate);
              console.log("Year of Random Date:", randomDate.getFullYear());
              console.log("Month of Random Date (0-11):", randomDate.getMonth());
              console.log("Day of Random Date:", randomDate.getDate());
                                  

2.4.1 The String Object

2.4.2 Evaluating Strings

2.4.3 Regular Expressions and the RegExp Object

2.4.4 The Array Object

2.4.5 The map() Method

2.4.6 The Date and Math Objects

Creating and Using Custom JavaScript Objects

Summary & Quick Review

2.5.1 Creating Custom Objects

  • Introduction: Custom objects in JavaScript represent complex data structures with properties and methods.

Using Object Literals

  • Object literals allow for straightforward object creation.
  • Simple Example:
  •                 
    let car = {
        make: "Toyota",
        model: "Camry",
        year: 2020,
        start: function() {
            console.log("Car started");
        }
    };
                    
                    
  • More Complex Example:
  •                 
    let book = {
        title: "1984",
        author: "George Orwell",
        pages: 328,
        read: function() {
            console.log(`Reading ${this.title} by ${this.author}`);
        }
    };
                    
                    

Using Constructor Functions

  • Constructor functions create multiple instances of an object type.
  • Simple Example:
  •                 
    function Person(name, age) {
        this.name = name;
        this.age = age;
        this.greet = function() {
            console.log(`Hello, my name is ${this.name}`);
        };
    }
                    
                    
  • More Complex Example:
  •                 
    function Rectangle(width, height) {
        this.width = width;
        this.height = height;
        this.area = function() {
            return this.width * this.height;
        };
    }
                    
                    

Using ES6 Classes

  • ES6 classes provide a structured way to create objects and handle inheritance.
  • Simple Example:
  •                 
    class Animal {
        constructor(name, species) {
            this.name = name;
            this.species = species;
        }
    
        speak() {
            console.log(`${this.name} makes a noise.`);
        }
    }
                    
                    
  • More Complex Example:
  •                 
    class Vehicle {
        constructor(make, model, year) {
            this.make = make;
            this.model = model;
            this.year = year;
        }
    
        getDetails() {
            return `${this.year} ${this.make} ${this.model}`;
        }
    }
                    
                    

Summary

  • Custom objects allow modeling of complex data structures.
  • Use object literals for simple objects, constructor functions for multiple instances, and ES6 classes for structured approaches.
  • Practice creating custom objects to enhance JavaScript skills.

2.5.2 Defining Properties and Methods

Defining Properties of Custom Objects

Properties in custom objects are variables that hold values, defining the characteristics or attributes of the object.

Example of Defining Properties:
Simple Example:
            
                let person = {
                    name: "Alice",
                    age: 30
                };

                console.log(person.name); // Output: Alice
                console.log(person.age);  // Output: 30
            
            
Complex Example:
            
                let car = {
                    make: "Toyota",
                    model: "Camry",
                    year: 2020,
                    color: "blue"
                };

                console.log(`Car: ${car.year} ${car.make} ${car.model}, Color: ${car.color}`); 
                // Output: Car: 2020 Toyota Camry, Color: blue
            
            
Defining Methods of Custom Objects

Methods in custom objects are functions that perform actions or calculations related to the object.

Example of Defining Methods:
Simple Example:
            
                let person = {
                    name: "Alice",
                    age: 30,
                    sayHello: function() {
                        console.log(`Hello, my name is ${this.name}`);
                    }
                };

                person.sayHello(); // Output: Hello, my name is Alice
            
            
Complex Example:
            
                let bankAccount = {
                    accountHolder: "Bob",
                    balance: 1000,
                    deposit: function(amount) {
                        this.balance += amount;
                        console.log(`Deposited: $${amount}. New balance: $${this.balance}`);
                    },
                    withdraw: function(amount) {
                        if (amount > this.balance) {
                            console.log("Insufficient funds.");
                        } else {
                            this.balance -= amount;
                            console.log(`Withdrew: $${amount}. New balance: $${this.balance}`);
                        }
                    }
                };

                bankAccount.deposit(500); // Output: Deposited: $500. New balance: $1500
                bankAccount.withdraw(200); // Output: Withdrew: $200. New balance: $1300
                bankAccount.withdraw(1500); // Output: Insufficient funds.
            
            
Summary

Defining properties and methods in custom objects is essential for creating structured and functional JavaScript applications. Properties represent the attributes of the object, while methods define the actions that can be performed on or by the object. Familiarize yourself with these concepts and practice creating custom objects with properties and methods to enhance your skills for the exam. Understanding how to effectively define and use properties and methods will significantly improve your ability to model real-world entities in JavaScript.

2.5.3 Creating New Instances

Creating New Object Instances

In JavaScript, you can create new instances of custom objects using constructor functions or ES6 classes. Each instance is independent and has its own set of properties and methods.

Creating Instances Using Constructor Functions
Simple Example:
            
        // Constructor function for creating Person objects
        function Person(firstName, lastName) {
            this.firstName = firstName;
            this.lastName = lastName;
            this.sayFullName = function() {
                console.log(`Full Name: ${this.firstName} ${this.lastName}`);
            };
        }

        // Creating new instances of Person
        let person1 = new Person("Bob", "Smith");
        let person2 = new Person("Alice", "Johnson");

        person1.sayFullName(); // Output: Full Name: Bob Smith
        person2.sayFullName(); // Output: Full Name: Alice Johnson
            
            
Complex Example:
            
        // Constructor function for creating Car objects
        function Car(make, model, year) {
            this.make = make;
            this.model = model;
            this.year = year;
            this.getDetails = function() {
                return `${this.year} ${this.make} ${this.model}`;
            };
        }

        // Creating new instances of Car
        let car1 = new Car("Toyota", "Camry", 2020);
        let car2 = new Car("Honda", "Civic", 2021);

        console.log(car1.getDetails()); // Output: 2020 Toyota Camry
        console.log(car2.getDetails()); // Output: 2021 Honda Civic
            
            
Creating Instances Using ES6 Classes
Simple Example:
            
        // Defining a class for Person
        class Person {
            constructor(firstName, lastName) {
                this.firstName = firstName;
                this.lastName = lastName;
            }

            sayFullName() {
                console.log(`Full Name: ${this.firstName} ${this.lastName}`);
            }
        }

        // Creating new instances of Person
        let person1 = new Person("Bob", "Smith");
        let person2 = new Person("Alice", "Johnson");

        person1.sayFullName(); // Output: Full Name: Bob Smith
        person2.sayFullName(); // Output: Full Name: Alice Johnson
            
            
Complex Example:
            
        // Defining a class for Car
        class Car {
            constructor(make, model, year) {
                this.make = make;
                this.model = model;
                this.year = year;
            }

            getDetails() {
                return `${this.year} ${this.make} ${this.model}`;
            }
        }

        // Creating new instances of Car
        let car1 = new Car("Toyota", "Camry", 2020);
        let car2 = new Car("Honda", "Civic", 2021);

        console.log(car1.getDetails()); // Output: 2020 Toyota Camry
        console.log(car2.getDetails()); // Output: 2021 Honda Civic
            
            
Summary

Creating new instances of custom objects in JavaScript allows you to model real-world entities with their own properties and methods. You can use constructor functions for traditional object creation or ES6 classes for a more modern approach. Familiarize yourself with these methods and practice creating instances to enhance your skills for the exam. Understanding how to create and manage object instances is fundamental to effective JavaScript programming.

2.5.4 Creating Client-Side Arrays Using Custom Objects

Creating Client-Side Arrays

In JavaScript, you can create arrays of custom objects to store and manipulate multiple instances of the same object type. This is useful for managing collections of data in a structured way.

Example of Creating Client-Side Arrays with Custom Objects
Simple Example:
            
        // Constructor function for creating Person objects
        function Person(firstName, lastName) {
            this.firstName = firstName;
            this.lastName = lastName;
            this.sayFullName = function() {
                console.log(`Full Name: ${this.firstName} ${this.lastName}`);
            };
        }

        // Creating an array to store multiple Person objects
        let people = [];

        // Adding Person objects to the array
        people.push(new Person("Bob", "Smith"));
        people.push(new Person("Alice", "Johnson"));
        people.push(new Person("Charlie", "Brown"));

        // Iterating over the array and calling the method for each Person
        people.forEach(function(person) {
            person.sayFullName();
            });
            
            
Complex Example:
            
        // Constructor function for creating Car objects
        function Car(make, model, year) {
            this.make = make;
            this.model = model;
            this.year = year;
            this.getDetails = function() {
                return `${this.year} ${this.make} ${this.model}`;
            };
        }

        // Creating an array to store multiple Car objects
        let cars = [];

        // Adding Car objects to the array
        cars.push(new Car("Toyota", "Camry", 2020));
        cars.push(new Car("Honda", "Civic", 2021));
        cars.push(new Car("Ford", "Mustang", 2019));

        // Iterating over the array and logging the details of each Car
        cars.forEach(function(car) {
            console.log(car.getDetails());
        });
            
            
Summary

Creating client-side arrays using custom objects allows you to manage collections of related data effectively. By storing multiple instances of the same object type in an array, you can easily iterate over them, manipulate their properties, and call their methods. Familiarize yourself with this concept and practice creating and using arrays of custom objects to enhance your skills for the exam. Understanding how to work with arrays of objects is essential for building robust JavaScript applications.

2.5.5 Functions & Methods for Manipulating Arrays

Creating Functions for Manipulating Arrays

Functions can be created to perform various operations on client-side arrays, such as adding, removing, or updating elements.

Example of Creating Functions for Manipulating Arrays
Simple Example:
            
        // Function to add a Person object to an array
        function addPerson(peopleArray, firstName, lastName) {
            let newPerson = new Person(firstName, lastName);
            peopleArray.push(newPerson);
        }

        // Constructor function for creating Person objects
        function Person(firstName, lastName) {
            this.firstName = firstName;
            this.lastName = lastName;
            this.sayHello = function() {
                console.log(`Hello, my name is ${this.firstName} ${this.lastName}`);
            };
        }

        // Creating an array to store Person objects
        let people = [];

        // Adding Person objects to the array
        addPerson(people, "Bob", "Smith");
        addPerson(people, "Alice", "Johnson");

        // Calling sayHello on each Person in the array
        people.forEach(function(person) {
            person.sayHello();
        });
            
            
Complex Example:
            
        // Function to remove a Person object from an array by first name
        function removePerson(peopleArray, firstName) {
            const index = peopleArray.findIndex(person => person.firstName === firstName);
            if (index !== -1) {
                peopleArray.splice(index, 1);
                console.log(`${firstName} has been removed from the array.`);
            } else {
                console.log(`${firstName} not found in the array.`);
            }
        }

        // Using the previous Person constructor and people array
        removePerson(people, "Alice"); // Output: Alice has been removed from the array.
        people.forEach(function(person) {
            person.sayHello(); // Output: Hello, my name is Bob Smith
        });
            
            
Creating Methods for Manipulating Arrays

Methods can also be added to custom objects to perform operations specific to those objects.

Example of Adding Methods to Custom Objects
Simple Example:
            
        // Adding a method to the Person constructor to list all people
        function Person(firstName, lastName) {
            this.firstName = firstName;
            this.lastName = lastName;
            this.sayHello = function() {
                console.log(`Hello, my name is ${this.firstName} ${this.lastName}`);
            };
        }

        // Adding a method to the array of Person objects
        Array.prototype.listPeople = function() {
            this.forEach(function(person) {
                person.sayHello();
            });
        };

        // Creating an array to store Person objects
        let people = [];
        people.push(new Person("Bob", "Smith"));
        people.push(new Person("Alice", "Johnson"));

        // Calling the custom method to list all people
        people.listPeople(); // Output: Hello, my name is Bob Smith
                            //         Hello, my name is Alice Johnson
            
            
Complex Example:
            
        // Adding a method to calculate the total number of people in the array
        Array.prototype.totalPeople = function() {
            return this.length;
        };

        // Using the previous people array
        console.log(`Total number of people: ${people.totalPeople()}`); // Output: Total number of people: 2
            
            
Summary

Creating functions and methods for manipulating client-side arrays is essential for managing collections of data effectively. Functions can be used to perform operations such as adding, removing, or updating elements in an array, while methods can be added to custom objects to encapsulate behavior specific to those objects. Familiarize yourself with these concepts and practice creating functions and methods to enhance your skills for the exam. Understanding how to manipulate arrays and custom objects will significantly improve your ability to build dynamic JavaScript applications.

2.5.6 Using Prototype Property, Classes, Constructors, Iterators, and Generators

1. Using the Prototype Property

The prototype property allows you to add new properties and methods to existing constructors. This means that all instances of a constructor can share these properties and methods, promoting code reuse.

Simple Example: Adding a Method to the Prototype
            
        function Person(name) {
            this.name = name;
        }

        Person.prototype.greet = function() {
            console.log(`Hello, my name is ${this.name}`);
        };

        const alice = new Person('Alice');
        alice.greet(); // Output: Hello, my name is Alice
            
            
Complex Example: Extending Built-in Objects
            
        Array.prototype.last = function() {
            return this[this.length - 1];
        };

        const numbers = [1, 2, 3, 4];
        console.log(numbers.last()); // Output: 4
            
            
2. Using Classes and Constructors

ES6 introduced the class keyword, which provides a clearer and more concise syntax for creating constructor functions and managing inheritance.

Simple Example: Defining a Class
            
        class Animal {
            constructor(name) {
                this.name = name;
            }

            speak() {
                console.log(`${this.name} makes a noise.`);
            }
        }

        const dog = new Animal('Dog');
        dog.speak(); // Output: Dog makes a noise.
            
            
Complex Example: Inheritance with Classes
            
        class Dog extends Animal {
            speak() {
                console.log(`${this.name} barks.`);
            }
        }

        const bulldog = new Dog('Bulldog');
        bulldog.speak(); // Output: Bulldog barks.
            
            
3. Using Iterators and Generators

Iterators are objects that implement the iterator protocol, which consists of a next() method that returns an object with value and done properties.

Simple Example: Creating an Iterator
            
        function createIterator(array) {
            let index = 0;
            return {
                next: function() {
                    if (index < array.length) {
                        return { value: array[index++], done: false };
                    } else {
                        return { done: true };
                    }
                }
            };
        }

        const iterator = createIterator([1, 2, 3]);
        console.log(iterator.next()); // Output: { value: 1, done: false }
        console.log(iterator.next()); // Output: { value: 2, done: false }
        console.log(iterator.next()); // Output: { value: 3, done: false }
        console.log(iterator.next()); // Output: { done: true }
            
            
Complex Example: Using Generators
            
        function* numberGenerator() {
            let index = 0;
            while (index < 3) {
                yield index++;
            }
        }

        const gen = numberGenerator();
        console.log(gen.next()); // Output: { value: 0, done: false }
        console.log(gen.next()); // Output: { value: 1, done: false }
        console.log(gen.next()); // Output: { value: 2, done: false }
        console.log(gen.next()); // Output: { done: true }
            
            
Summary
  • Prototype Property: Allows adding methods and properties to constructors, enabling shared functionality.
  • Classes and Constructors: ES6 syntax simplifies object-oriented programming and inheritance.
  • Iterators and Generators: Iterators provide a way to traverse a collection, while generators allow for lazy evaluation and stateful function execution.

This guide should help you revise and understand the key concepts related to prototypes, classes, constructors, iterators, and generators in JavaScript. Familiarizing yourself with these concepts will enhance your ability to write efficient and organized code.

2.5.1 Creating Custom Objects

2.5.2 Defining Properties and Methods

2.5.3 Creating New Instances

2.5.4 Creating Client-Side Arrays Using Custom Objects

2.5.5 Functions & Methods for Manipulating Arrays

2.5.6 Using Prototype Property, Classes, Constructors, Iterators, and Generators

Sub Topic

Sub Topic

Recommended Readings