Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
100% found this document useful (3 votes)
5K views

The JavaScript Workbook - Download Edition

This document provides a detailed table of contents for a book titled "The JavaScript Development Workbook" by Mark Lassoff. The book aims to teach JavaScript fundamentals through a practice-based approach. It covers topics like variables, data types, control flow, loops, functions, arrays, objects, and error handling. Each section provides code exercises and examples to help readers learn and practice JavaScript concepts in a hands-on way. The book uses real-world analogies and metaphors to explain programming concepts and provides critical points and FAQs to reinforce learning.

Uploaded by

rohini kale
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
100% found this document useful (3 votes)
5K views

The JavaScript Workbook - Download Edition

This document provides a detailed table of contents for a book titled "The JavaScript Development Workbook" by Mark Lassoff. The book aims to teach JavaScript fundamentals through a practice-based approach. It covers topics like variables, data types, control flow, loops, functions, arrays, objects, and error handling. Each section provides code exercises and examples to help readers learn and practice JavaScript concepts in a hands-on way. The book uses real-world analogies and metaphors to explain programming concepts and provides critical points and FAQs to reinforce learning.

Uploaded by

rohini kale
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 221

JAVASCRI

PT
DEVE
LOPME
NT
WO
RKB
OOK
T
he
Pr
ov
en
,A
ct
i
ve
Way
to
Le
ar
nJ
AV
AS
CR
I
PT

M
AR
KL
AS
SO
FF
The JavaScript
Development Workbook
A Practice-Based Approach to Learning
JavaScript Fundamentals
The JavaScript Development Workbook
A Practice-Based Approach to Learning JavaScript
Fundamentals

Mark Lassoff

ISBN: 9798393425623

Framework Tech Media


6 West River Street #225
Milford, CT 06460

©2023
© 2023 LearnToProgram.tv, LLC d/b/a Framework Tech Media.
All rights reserved. No part of this book may be reproduced or
transmitted in any form or by any means, electronic or
mechanical, including photocopying, recording or by any
information storage and retrieval system, without written
permission from the author, except for the inclusion of brief
quotations in a review.

Note that this notice informs readers that all rights are
reserved and prohibits the reproduction or transmission of any
part of the book without written permission from the author. It
also allows for the inclusion of brief quotations in a review, in
accordance with fair use laws.
For Mom and Rick. Thank you for everything.
Detailed Table of Contents

Introduction 13
Section 1: JavaScript Quick Start 15
Introduction 15
Setting up your development environment 15
Choosing a Text Editor 16
Creating an HTML File 17
Creating a JavaScript File 17
Linking JavaScript to HTML 18
Running Your Code 18
More On Running JavaScript Code 18
Using the Browser Console 18
Using an HTML File 19
Using a Code Editor 20
Best Practices for Testing Your Code 20
Basic JavaScript Concepts and Syntax 20
Console.log 21
Variables 23
Data Types 23
Operators 25
Arithmetic Operators 25
Comparison Operators 25
Logical Operators 25
Functions 26
Code Exercises 26
Section 2: Variables and Data Types 29
Introduction 29
Declaring Variables 30
Variable Types 30
Let vs. Const 31
Best Practices 32
Primitive Data Types 32
Strings 32
Numbers 33
Booleans 34
Null 34
Undefined 34
Complex Data Types 35
Arrays 35
Objects 36
Functions 37
Type Coercion and Conversion 37
Type Coercion 38
Type Conversion 38
Loose vs Strict Equality 39
Critical Points 40
The FAQ 41
Code Exercises 42
Section 3: Control Flow and Loops 44
Introduction 44
Conditional Statements 44
If/Else Statements 45
Switch/Case Statements 46
The prompt() Function 47
Code Exercises 47
Iteration Statements (for, while, do/while) 48
The for Loop 48
The while Loop 49
The do/while Loop 49
Choosing the Right Loop 50
Code Exercises 51
Loop control statements (break, continue) 52
The break statement 52
The continue statement 53
Combining break and continue 53
Coding Exercises 54
Critical Points 55
The FAQ 56
Section 4: JavaScript Functions 57
Introduction 57
Declaring and Calling Functions 57
Declaring Functions 58
Calling Functions 58
Function Return Values 59
Function Parameters and Arguments 59
Defining Function Parameters 60
Using Function Arguments 60
Default Parameter Values 61
Rest Parameters 61
Code Exercises 62
Function expressions and arrow functions 63
Function Expressions 63
Arrow Functions 63
Code Exercise 64
Function Scope and Closures 65
Function Scope 65
Global Scope 66
Closures 67
Code Exercises 68
Critical Points 68
The FAQ 70
Section 5: Working with Arrays 72
Declaring and initializing arrays 72
Declaring Arrays 72
Initializing Arrays 73
Accessing Array Members 74
Addressing Non-Existent Array Members 74
Multidimensional Arrays 75
Array methods (push, pop, shift, unshift, etc.) 76
Adding Elements with push() and unshift() 76
Removing Elements with pop() and shift() 77
Modifying Elements in an Array with splice() 77
Finding Elements in an Array with indexOf() 77
Checking If an Array Includes an Element with
includes() 78
The slice() method 78
The splice() method 78
The concat() method 79
Converting Arrays to Strings and Vice Versa 79
The join() method 79
The split() method 80
Iterating Through Arrays with For and While Loops 81
Iterating Through Arrays with a For Loop 81
Iterating Through Arrays with a While Loop 82
Iterating over arrays (forEach, map, filter, reduce) 83
forEach() 83
map() 84
filter() 85
Code Exercises 86
Critical Points 88
The FAQ 90
Section 6: Objects in JavaScript 92
Built-in JavaScript Objects Versus Custom Objects 92
Built-In Objects 92
Custom Objects 93
Properties and Methods 93
Prototypes and Inheritance 93
Objects, Instances, Properties and: A Metaphor 94
Creating Objects: Object literals and constructors 95
Object Literals 95
Constructors 96
Comparing Object Literals and Constructors 97
Properties and methods 97
Accessing Properties 97
Modifying Properties 98
Methods 98
Prototypes and inheritance 99
Introduction to Prototypes 99
Creating a Prototype Object 100
Creating an Object with a Prototype 100
Inheritance and the Prototype Chain 100
Overriding Properties and Methods 101
Classes and Objects in the Real World: Vehicles 101
Creating the Vehicle Class 101
Inheriting Properties and Methods 102
Using the Classes 104
Creating an Ambulance 104
Creating a Bus 104
Using the Methods 105
Inheritance in Action 105
Code Exercises 106
Critical Points 107
The FAQ 108
Section 7: Error Handling 110
Types of errors (syntax, runtime, logic) 110
Syntax Errors 110
Runtime Errors 111
Logic Errors 111
Using Developer Tools in Your Browser 112
Reviewing the Console 112
Tracing Variables 112
Inserting Breakpoints 113
Code Exercise 113
try/catch/finally statements 116
The try Block 116
The catch Block 116
The finally Block 117
Putting it All Together 117
Code Exercise 118
Throwing and catching exceptions 119
The throw statement 119
The try and catch statements 120
The finally statement 120
Code Exercise 121
Critical Points 122
The FAQ 123
Section 8: DOM Manipulation 125
The Document Object Model (DOM) 125
DOM Tree Structure 126
Accessing DOM elements 126
getElementById() 126
querySelector() 126
querySelectorAll() 127
Elements by Tag Name or Class Name 127
Dom Manipulation: In Action 127
Modifying DOM Elements 129
Modifying Text Content 129
Modifying HTML Content 130
Modifying Attributes 131
Modifying CSS 132
Modifying inline styles 132
Modifying classes 133
Responding to events 135
Event Listeners 135
Event Handling 135
Event Propagation 136
The Event Object 136
The Event Object Applied 138
Code Exercises 139
Critical Points 143
The FAQ 145
Section 9: Asynchronous JavaScript 147
Callback functions 147
Passing Functions as Arguments 148
Nested Callbacks 148
Promises 150
Introduction to Promises 150
Creating a Promise 150
Consuming a Promise 151
Chaining Promises 151
Error Handling with Promises 152
Async/await 153
What is Async/Await? 153
Async Functions 153
Error Handling 154
Using Async/Await with Promise.all 155
Using the Fetch API for HTTP requests 155
Sending a GET Request with Fetch 156
Handling Errors with Fetch 156
Using Async/Await with Fetch 157
Parsing XML data from APIs 158
Parsing JSON Data Returned from an API 160
Code Exercise 161
Critical Points 162
The FAQ 163
Section 10: JavaScript Tools and Libraries 164
Node.js and npm 165
Installing Node.js and NPM 166
Creating a Node.js Project 166
Using Third-Party Packages 166
Webpack and Babel 167
Installing Webpack and Babel 168
Configuring Webpack and Babel 168
React and other front-end frameworks 169
Introduction to React 169
Creating a React Component 169
Rendering a Component 170
Handling Events 171
Express and other back-end frameworks 172
Installing Express 172
Creating an Express Server 172
Handling Requests and Responses 173
Using Other Back-end Frameworks 174
Testing frameworks (Jest, Mocha, etc.) 174
Writing Tests with Jest 174
Writing Tests with Mocha 175
Code Coverage 176
Critical Points 177
The FAQ 178
Section 11: JavaScript Projects 180
Project: Weather App 180
Project: To Do List 181
Project: Calculator 181
Project: Random Quote Generator 182
Project: Memory Game 182
Project: Hangman 183
Project: Recipe App 183
Project: BART Transit Tracker 184
Project: Explore Your City 184
Excerise Soutions 186
Introduction
Hi there! I'm excited to introduce you to my book, "The
JavaScript Development Workbook." This book is all about
learning JavaScript through practical coding exercises and
projects. Whether you're a complete beginner or you already
have some programming experience, this book is designed to
help you build a strong foundation in JavaScript.

The JavaScript Development Workbook is an ideal resource for


self-study or as a text for a classroom setting. Instructors can
use the book as a primary text or as a supplementary resource
in a programming course. The projects and coding exercises
make it easy to create assignments, and the clear explanations
and example code allow students to quickly grasp the
concepts.

Additionally, the book includes an FAQ section and critical


points for each chapter, making it easy for instructors to guide
students through the material and answer common questions.
With dozens of coding exercises and projects, this book will
help students develop a strong foundation in JavaScript
programming and prepare them for real-world applications.

One of the key features of this book is the dozens of code


exercises and projects scattered throughout each chapter.
These exercises are essential to truly understanding and
mastering JavaScript. They will challenge you to think critically,
apply what you've learned, and build your own code from
scratch.

As you work through the code exercises, remember that each


one has a suggested answer at the end of the book. If you find
yourself struggling to get an exercise to work correctly, don't
worry! It's normal to face challenges when learning to code.

Page 13
Take a moment to review the suggested answer and try to
understand where you went wrong. It's important to
remember that many coding errors seem obvious once you've
found them, but they can still take a great deal of time to
locate. Be patient with yourself and don't get discouraged. This
is all part of the learning process, and every new developer
goes through it.

To get the most out of this book, I recommend setting aside


dedicated time each day or week to work through the
exercises and projects. Make sure you have a solid grasp of
each concept before moving on to the next one. Don't be afraid
to experiment and try things out on your own, too!

By the end of this book, you'll have a strong foundation in


JavaScript and be able to build your own web applications.
Whether you're interested in front-end development with
frameworks like React, or back-end development with Node.js
and Express, this book will prepare you for the next steps in
your programming journey.

So, what are you waiting for? Let's dive in and start coding!

Page 14
Section 1: JavaScript Quick Start

Introduction
JavaScript is a programming language that's like a Swiss Army
knife: it can be used for all sorts of things, from creating
interactive web pages to building complex web applications
and even running on servers. As a JavaScript developer, you'll
have a lot of power in your hands to create cool and useful
things.

In this chapter, we're going to start with the basics of


JavaScript. Don't worry if you're brand new to coding, we'll take
it slow and easy. We'll dive into some of the building blocks of
JavaScript code, such as variables, operators, and functions.
And don't worry if some of these terms sound foreign to you
right now, we'll explain them in plain English.

By the end of this chapter, you'll have written your first


JavaScript program! It's like leveling up in a video game, but
with code. And who knows, maybe you'll enjoy it so much that
you'll want to become a professional JavaScript developer. Or
at the very least, impress your friends with your new nerdy
skills.

So, grab your keyboard and let's get started!

Setting up your development environment


In order to write and run JavaScript code, you'll need a
development environment. In this section, we'll go over the
basics of setting up your development environment for
JavaScript. Don't worry, it's not as complicated as it sounds!

Page 15
Choosing a Text Editor
The first thing you'll need is a text editor. A text editor is a
software application that allows you to write and edit text,
including code. There are many options to choose from, both
free and paid.

Some popular text editors for JavaScript development include:

● Visual Studio Code: A free, open-source text editor


developed by Microsoft.
● Sublime Text: A lightweight, customizable text editor
with a cult following.
● Atom: A free, open-source text editor developed by
GitHub.

Editing a Text File in Visual Studio Code from Microsoft. This free
editor is used by millions of professional developers.

Each text editor has its own strengths and weaknesses, so it's
worth trying a few out to see which one you like best. I
personally use Visual Studio Code and highly recommend it!

Page 16
Creating an HTML File
Before we can write JavaScript code, we need a web page to
run it on. In order to create a web page, we'll need to write
some HTML code.

Here's a basic HTML file to get you started:

<!DOCTYPE html>
<html>
<head>
<title>My JavaScript Page</title>
</head>
<body>
<h1>Hello, world!</h1>
<script src="main.js"></script>
</body>
</html>

This HTML file sets up a basic web page with a heading and a
reference to a JavaScript file called main.js. We'll create the
main.js file in the next section.

Creating a JavaScript File


Now that we have our HTML file set up, we can create a
JavaScript file to write our code in. In your text editor, create a
new file called main.js in the same directory as your HTML file.

Here's a basic example of some JavaScript code:

console.log("Hello, world!");

Page 17
Linking JavaScript to HTML
Now that we have our HTML file and our JavaScript file, we
need to link them together. In our HTML file, we already added
a reference to our main.js file in the body section. This tells the
browser to load the JavaScript file and run any code it contains.

Running Your Code


Now that everything is set up, we can run our code! Open your
HTML file in a web browser (just double-click on the file) and
open the console (usually by pressing F12 or Ctrl+Shift+J). You
should see the "Hello, world!" message appear in the console.

Congratulations, you've set up your development environment


for JavaScript! You're now ready to start writing and running
your own JavaScript code.

Remember, the best way to learn is by doing. So don't be afraid


to experiment and make mistakes! And if you ever get stuck,
don't hesitate to reach out for help.

More On Running JavaScript Code


Now that you've set up your development environment and
written some JavaScript code, it's time to learn how to run it. In
this section, we'll go over the different ways to run JavaScript
code and some best practices for testing your code.

Using the Browser Console


One of the easiest ways to run JavaScript code is through the
browser console. Most modern web browsers come with a
console built-in, which allows you to execute JavaScript code
directly in the browser.

To open the console, right-click anywhere on a web page and


select "Inspect" or "Inspect Element" from the context menu.

Page 18
This will open the browser's developer tools. From there, you
can select the "Console" tab to access the console.

Once you have the console open, you can enter JavaScript
code directly into the console and press Enter to run it. Here's
an example:

console.log("Hello, world!");

In this code, we're using the console.log() method to print the


message "Hello, world!" to the console. When you run this code
in the console, you should see the message appear in the
console.

Using an HTML File


Another way to run JavaScript code is by creating an HTML file
and linking to your JavaScript file in the file. This allows you to
see the output of your code directly in the web page.

Here's an example HTML file that links to a JavaScript file:

<!DOCTYPE html>
<html>
<head>
<title>My JavaScript Page</title>
</head>
<body>
<h1>Hello, world!</h1>
<script src="main.js"></script>
</body>
</html>

In this code, we're linking to a JavaScript file called main.js. This


file should contain your JavaScript code, which will be
executed when the web page loads.

Page 19
Using a Code Editor
If you're working on a larger JavaScript project, you may want
to use a code editor to write and run your code. Code editors
like Visual Studio Code or Sublime Text allow you to write and
run JavaScript code directly in the editor, without the need for
a web browser.

Most code editors have built-in features for running and testing
your code. For example, in Visual Studio Code, you can use the
built-in debugger to step through your code and find any
errors.

Best Practices for Testing Your Code


When you're writing and testing JavaScript code, it's important
to follow some best practices to ensure that your code is
working correctly. Here are a few tips:

Use descriptive variable and function names to make your


code easier to understand.
● Comment your code to explain what it does and why.
● Test your code on different browsers to ensure
compatibility.
● Use console.log() to debug your code and see what's
happening behind the scenes.
● By following these best practices, you can ensure that
your JavaScript code is clean, readable, and working
correctly.

Basic JavaScript Concepts and Syntax


Alright, it's time to get our hands dirty and start writing some
JavaScript code! But before we do that, let's first go over some
of the basic concepts and syntax you need to know.

Page 20
We’ll revisit many of these concepts later and in greater detail,
but, I want to get you moving with JavaScript– and actually
coding– as soon as possible!

JavaScript is a language that is interpreted by web browsers,


allowing developers to make web pages come to life with
interactivity and animation. It is a high-level programming
language, meaning that it abstracts away some of the
lower-level details of programming, making it easier for
humans to read and write code.

Console.log
Initially in this work book, we’ll be logging our JavaScript
results ot the browser console. This avoids having to introduce
confusing code earlier than you’re ready for it.

console.log() is a method in JavaScript that allows you to print


messages or values to the browser console. The console is a
powerful tool for debugging and testing your code. You can
use it to inspect and interact with JavaScript code on a web
page.

To open the console in most modern browsers, you can


right-click anywhere on a web page and select "Inspect" or
"Inspect Element" from the context menu. This will open the
browser's developer tools. From there, you can select the
"Console" tab to access the console.

Page 21
The console.log() results are shown on the right in the browser
window.

Once you have the console open, you can use console.log() to
print messages or values to the console. Here's an example:

console.log("Hello, world!");

In this example, we're using console.log() to print the message


"Hello, world!" to the console. When you run this code, you
should see the message appear in the console.

You can also use console.log() to print values of variables or


expressions to the console. Here's an example:

let x = 5;
let y = 10;
console.log(x + y);

In this example, we're using console.log() to print the result of


adding x and y to the console. When you run this code, you
should see the value 15 appear in the console.

Using console.log() can be a helpful way to debug your code


and see what's going on behind the scenes. I hope this

Page 22
explanation helps you get started with using the console in
your JavaScript projects!

Now let’s dive in to a quick introduction to some of the most


important components of JavaScript– remember these will all
be reviewed in detail later in this books.

Variables
Variables are used to store data in JavaScript. They're like
labeled boxes that hold values that can be changed. Here's an
example:

let myName = "Alice";


console.log(myName); // outputs "Alice"
myName = "Bob";
console.log(myName); // outputs "Bob"

In this example, we create a variable called myName and


assign it the value "Alice". We then log the value of myName to
the console using the console.log() function. We then re-assign
the variable to the value "Bob" and log it to the console again.
Notice how the value of the variable changes!

Data Types
JavaScript has several built-in data types, including strings,
numbers, booleans, arrays, and objects. Let's go over each one
briefly.

Strings
Strings are used to represent text in JavaScript. They are
enclosed in either single quotes (') or double quotes ("). Here's
an example:

let myString = "Hello, world!";

Page 23
console.log(myString);

Numbers
Numbers are used to represent numeric values in JavaScript.
They can be integers or floating-point numbers. Here's an
example:

let myNumber = 42;


console.log(myNumber);

Booleans
Booleans are used to represent true/false values in JavaScript.
They can be either true or false. Here's an example:

let myBoolean = true;


console.log(myBoolean);

Arrays
Arrays are used to store collections of data in JavaScript. They
are enclosed in square brackets ([]). Here's an example:

let myArray = [1, 2, 3, 4, 5];


console.log(myArray);

Objects
Objects are used to represent complex data structures in
JavaScript. They are enclosed in curly braces ({}) and consist of
key-value pairs. Here's an example:

let myObject = {name: "Alice", age: 30, isProgrammer:


true};
console.log(myObject);

Page 24
Operators
Operators are used to perform operations on values in
JavaScript. There are several types of operators, including
arithmetic, comparison, and logical operators.

Arithmetic Operators
Arithmetic operators are used to perform basic math
operations in JavaScript. Here are some examples:

let x = 10;
let y = 5;
console.log(x + y); // outputs 15
console.log(x - y); // outputs 5
console.log(x * y); // outputs 50
console.log(x / y); // outputs 2

Comparison Operators
Comparison operators are used to compare values in
JavaScript. They return a boolean value (true or false). Here are
some examples:

let x = 10;
let y = 5;
console.log(x);

Logical Operators
Logical operators are used to combine boolean values in
JavaScript. There are three logical operators: && (and), || (or),
and ! (not). Here are some examples:

Page 25
let x = 10;
let y = 5;
console.log(x > 5 && y < 10); // outputs true
console.log(x > 5 || y > 10); // outputs true
console.log(!(x > 5)); // outputs false

Functions
Functions are reusable blocks of code that perform a specific
task. They can take input (called parameters) and return
output. Here's an example:

function sayHello(name) {
console.log("Hello, " + name + "!");
}

sayHello("Alice"); // outputs "Hello, Alice!"


sayHello("Bob"); // outputs "Hello, Bob!"

In this example, we define a function called sayHello that takes


one parameter (name). When we call the function with the
argument "Alice", it logs "Hello, Alice!" to the console. When we
call it with the argument "Bob", it logs "Hello, Bob!".

That's it for the basic concepts and syntax of JavaScript! This


may seem like a lot to take in, but don't worry, we'll be
practicing all of these concepts throughout the book. By the
end of it, you'll be a JavaScript pro (or at least well on your way).

Code Exercises
It may be premature to provide code exercises at this point–
You’ve only just started. However, I did decide to include some
here so you can see the types of problems you’ll be solving with

Page 26
JavaScript. You’re welcome to give them a shot, or wait and
come back when you have a more solid footing.

As wil all code exercsies, the answers are in the back of the
book! Good luck.

Exercise 1.1: Simple variable manipulation


In this exercise, you will declare two variables and log them to
the console. Follow these steps:

1. Declare a variable called myNumber and assign it the


value 42.
2. Declare a second variable called myString and assign it
the value "Hello, world!".
3. Log both variables to the console.

Exercise 1.2: Using arithmetic operators


In this exercise, you will perform basic math operations using
variables. Follow these steps:

1. Declare two variables called x and y and assign them


both a number.
2. Log the result of adding x and y to the console.
3. Log the result of subtracting y from x to the console.
4. Log the result of multiplying x and y to the console.
5. Log the result of dividing x by y to the console.

Exercise 1.3: Using comparison operators


In this exercise, you will compare values using comparison
operators. Follow these steps:

1. Declare two variables called a and b and assign them


both a number.
2. Log the result of checking if a is greater than b to the
console.
3. Log the result of checking if a is less than or equal to b
to the console.

Page 27
4. Log the result of checking if a is equal to b to the
console.
5. Log the result of checking if a is not equal to b to the
console.

Exercise 1.4: Using logical operators


In this exercise, you will combine boolean values using logical
operators. Follow these steps:

1. Declare two variables called x and y and assign them


both a boolean value.
2. Log the result of x AND y to the console.
3. Log the result of x OR y to the console.
4. Log the result of NOT x to the console.

Exercise 1.5: Function creation


In this exercise, you will create a function and call it with
arguments. Follow these steps:

1. Create a function called multiply that takes two


numbers as parameters and returns their product.
2. Create a variable called result and assign it the value of
calling the multiply function with the numbers 5 and 10
as arguments.
3. Log the value of result to the console.

Page 28
Section 2: Variables and Data
Types

Introduction
In this section, we'll be diving into the wonderful world of
variables and data types. If you're new to programming, these
concepts might seem a bit confusing at first, but fear not - we'll
take it step by step and make sure you understand everything
before moving on.

First up, we'll be discussing how to declare variables in


JavaScript. Variables are like containers that hold values, and
they're used in just about every program you'll ever write. We'll
cover the let keyword, variable naming conventions, and best
practices for declaring variables.

Next, we'll be looking at primitive data types. These are the


building blocks of JavaScript, and they include things like
strings, numbers, and boolean values. We'll cover what each of
these data types are, how to use them, and some common
gotchas to watch out for.

After that, we'll be exploring complex data types. These are


more advanced data types that allow you to store collections of
data or reusable code. We'll cover objects and functions, two of
the most important complex data types in JavaScript, and
show you how to use them in your own programs.

Finally, we'll wrap up this section with a discussion of type


coercion and conversion. This is a tricky topic, but an important
one to understand, as it can affect how your program runs and
behaves. We'll cover what type coercion is, how to avoid it
when you don't want it, and how to perform explicit type
conversions when you need to.

Page 29
So buckle up, grab a cup of coffee (or tea, we don't judge), and
let's dive into variables and data types in JavaScript!

Declaring Variables
In JavaScript, variables are used to store data values. In this
section, we'll go over the basics of declaring variables in
JavaScript, including different variable types and naming
conventions.

Variable Types
JavaScript has several different variable types, including:

● Number: Used to store numeric values.


● String: Used to store text values.
● Boolean: Used to store true/false values.
● Array: Used to store a collection of values.
● Object: Used to store a collection of key-value pairs.

To declare a variable in JavaScript, you can use the let or const


keyword, followed by the variable name and an optional initial
value. Here's an example:

let myNumber = 42;


const myString = "Hello, world!";
let myBoolean = true;
let myArray = [1, 2, 3];
let myObject = {name: "John", age: 30};

Naming Conventions
When naming variables in JavaScript, there are some
conventions to follow to make your code more readable and
understandable. Here are a few tips:

Page 30
Use descriptive variable names that describe the purpose of
the variable.
● Start variable names with a lowercase letter.
● Use camelCase to separate words within a variable
name.
● Avoid using reserved keywords as variable names (e.g.
let, if, while, etc.)

Here's an example of good variable naming:

let myFavoriteColor = "blue";


let numberOfStudents = 25;
let hasPermission = true;

Let vs. Const


In JavaScript, there are two keywords for declaring variables: let
and const. The main difference between these two keywords is
that let allows the variable to be reassigned, while const does
not.

Here's an example of using let:

let myNumber = 42;


myNumber = 10;
console.log(myNumber); // 10

In this code, we're declaring a variable called myNumber and


assigning it the value 42. We're then reassigning the value of
myNumber to 10, which is allowed because we used let.

Here's an example of using const:

const myNumber = 42;


myNumber = 10; // This will throw an error!

Page 31
console.log(myNumber);

Best Practices
When declaring variables in JavaScript, it's important to follow
some best practices to ensure that your code is clean, readable,
and error-free. Here are a few tips:

● Always declare variables before using them.


● Use descriptive variable names that clearly describe the
purpose of the variable.
● Use const for variables that will not be reassigned, and
let for variables that may be reassigned.
● Avoid using global variables whenever possible.

By following these best practices, you can ensure that your


JavaScript code is clean, readable, and error-free.

Congratulations, you've learned the basics of declaring


variables in JavaScript!

Primitive Data Types


In JavaScript, there are five primitive data types: string,
number, boolean, null, and undefined. These data types are
called "primitive" because they are not objects and do not have
any methods of their own. In this section, we'll go into more
detail about each of these data types.

Strings
Strings are used to represent text in JavaScript. They can be
created using either single or double quotes, like this:

let myString = 'Hello, world!';

Page 32
In addition to single and double quotes, you can also create
strings using backticks (`), which allow you to include variables
and expressions inside the string using ${...} syntax:

let name = 'John';


console.log(`Hello, ${name}!`);

In this code, we're using backticks to create a string that


includes the value of the name variable.

Strings also have a number of built-in properties and methods.


For example, you can get the length of a string using the
length property:

let myString = 'Hello, world!';


console.log(myString.length);

This will print the length of the string to the console.

Numbers
Numbers are used to represent numeric values in JavaScript.
They can be integers or decimals, positive or negative. Here's
an example:

let myNumber = 42;

In addition to regular numbers, JavaScript also has two special


number values: Infinity and -Infinity, which represent positive
and negative infinity, respectively. There is also a special value
called NaN, which stands for "Not a Number", and is returned
when a mathematical operation cannot be performed.

Page 33
Booleans
Booleans are used to represent true/false values in JavaScript.
They can be either true or false. Here's an example:

let myBoolean = true;

Boolean values are often used in conditional statements.

Null
Null is a special value in JavaScript that represents a deliberate
non-value. It is often used to indicate that a variable has no
value or that an object property does not exist. Here's an
example:

let myNull = null;

In this code, we're declaring a variable called myNull and


assigning it a value of null.

Undefined
Undefined is a value in JavaScript that indicates that a variable
has been declared but has not yet been assigned a value.
Here's an example:

let myUndefined;
console.log(myUndefined); // Output: undefined
In this code, we're declaring a variable called myUndefined but
not assigning it a value. When we print the value of
myUndefined to the console, we get the value undefined.

This concludes our overview of the primitive data types in


JavaScript. In the next section, we'll learn about complex data
types.

Page 34
Complex Data Types
In addition to the primitive data types covered in the previous
section, JavaScript also has several complex data types. These
data types are "complex" because they are objects and have
methods and properties of their own.

Arrays
Arrays are used to store collections of data in JavaScript. They
can be created using square brackets and can contain any
combination of data types, including other arrays. Here's an
example:

let myArray = ['apple', 'banana', 'orange'];

In this code, we're declaring an array called myArray that


contains three string values.

Arrays have a number of built-in methods, including push(),


which adds an element to the end of the array, and pop(),
which removes the last element from the array:

let myArray = ['apple', 'banana', 'orange'];


myArray.push('grape');
console.log(myArray); // Output: ['apple', 'banana',
'orange', 'grape']

myArray.pop();
console.log(myArray); // Output: ['apple', 'banana',
'orange']

Page 35
Objects
Objects are used to store collections of key-value pairs in
JavaScript. They can be created using curly braces and can
contain any combination of data types, including other objects.
Here's an example:

let myObject = {
name: 'John',
age: 30,
hobbies: ['reading', 'running', 'cooking'],
};

In this code, we're declaring an object called myObject that


contains three key-value pairs. The keys are name, age, and
hobbies, and the values are a string, a number, and an array,
respectively.

Objects also have a number of built-in methods, including


Object.keys(), which returns an array of the object's keys, and
Object.values(), which returns an array of the object's values:

let myObject = {
name: 'John',
age: 30,
hobbies: ['reading', 'running', 'cooking'],
};

let myObjectKeys = Object.keys(myObject);


console.log(myObjectKeys); // Output: ['name', 'age',
'hobbies']

let myObjectValues = Object.values(myObject);


console.log(myObjectValues); // Output: ['John', 30,
['reading', 'running', 'cooking']]

Page 36
Functions
Functions are used to encapsulate blocks of code and can be
called or invoked at any time. They can take parameters and
return values. Here's an example:

function addNumbers(a, b) {
return a + b;
}

let result = addNumbers(3, 5);


console.log(result); // Output: 8

In this code, we're declaring a function called addNumbers


that takes two parameters, a and b, and returns their sum. We
then call the addNumbers function and pass in the values 3
and 5, and store the result in a variable called result. Finally, we
print the value of result to the console.

Functions also have a number of advanced features, including


function expressions and closures, which we'll cover in later
sections.

This concludes our overview of the complex data types in


JavaScript. In the next section, we'll learn about type coercion
and conversion.

Type Coercion and Conversion


In JavaScript, it's common to encounter situations where one
data type needs to be converted to another. This can happen
implicitly or explicitly. In this section, we'll cover the concepts of
type coercion and conversion, and how they work in JavaScript.

Page 37
Type Coercion
Type coercion is the process of converting a value from one
data type to another implicitly. This can happen when you
perform an operation between two different data types. For
example:

let myString = '5';


let myNumber = 2;

console.log(myString + myNumber); // Output: '52'

In this code, we're performing an operation between a string


(myString) and a number (myNumber). The result is a string
that concatenates the two values.

Type coercion can be useful in some situations, but it can also


lead to unexpected behavior if you're not careful.

Type Conversion
Type conversion is the process of explicitly converting a value
from one data type to another. This can be done using built-in
JavaScript functions, such as Number(), String(), and Boolean().
For example:

let myString = '5';


let myNumber = Number(myString);

console.log(myNumber); // Output: 5

In this code, we're converting the string value myString to a


number using the Number() function.

Here are some examples of other data type conversions you


might encounter in JavaScript:

Page 38
// Converting a number to a string
let myNumber = 5;
let myString = String(myNumber);

console.log(myString); // Output: '5'

// Converting a boolean to a number


let myBoolean = true;
let myNumber = Number(myBoolean);

console.log(myNumber); // Output: 1

Loose vs Strict Equality


When comparing values in JavaScript, you can use two
different types of equality: loose and strict.

Loose equality (==) compares two values for equality after type
coercion, while strict equality (===) compares two values for
equality without type coercion.

Here's an example:

let myString = '5';


let myNumber = 5;

console.log(myString == myNumber); // Output: true


console.log(myString === myNumber); // Output: false

In this code, we're comparing the string value myString to the


number value myNumber. With loose equality, JavaScript
performs type coercion and determines that the values are
equal. With strict equality, the values are not equal because
they are different data types.

Page 39
It's generally considered best practice to use strict equality
whenever possible to avoid unexpected behavior.

Critical Points
Declaring variables:

● Use the let keyword to declare a variable.


● Variables can store different types of data, including
numbers, strings, and boolean values.
● Use descriptive variable names to make your code more
readable.

Primitive data types:

● JavaScript has six primitive data types: string, number,


boolean, null, undefined, and symbol.
● Primitive data types are immutable, meaning their
values cannot be changed.
● Use the typeof operator to check the data type of a
variable.

Complex data types:

● JavaScript has two complex data types: object and


function.
● Objects are collections of key-value pairs, while
functions are blocks of code that can be reused.

Type coercion and conversion:

● Type coercion is the process of converting a value from


one data type to another implicitly.
● Type conversion is the process of explicitly converting a
value from one data type to another.
● You can use built-in JavaScript functions like Number(),
String(), and Boolean() to convert between data types.

Page 40
● Be aware of type coercion when performing operations
between different data types, as it can lead to
unexpected results.

The FAQ
Q: What is the difference between let, const, and var for
declaring variables?
A: let and const are block-scoped variables, while var is
function-scoped. let variables can be reassigned, while const
variables cannot. It's generally recommended to use const for
variables that won't be reassigned, and let for variables that
might be reassigned.

Q: What is type coercion and when does it happen?


A: Type coercion is the process of converting a value from one
data type to another implicitly. It happens when you perform
an operation between two different data types, or when you
pass a value to a function that expects a different data type.

Q: What is the difference between a primitive data type and a


complex data type?
A: Primitive data types are simple, immutable values, while
complex data types are collections of data that can be
mutated. Examples of primitive data types include strings,
numbers, and boolean values, while examples of complex data
types include objects and functions.

Q: How do you convert a string to a number in JavaScript?


A: You can use the built-in Number() function to convert a
string to a number. For example: let myString = '5'; let
myNumber = Number(myString);.

Q: What is the difference between loose and strict equality in


JavaScript?

Page 41
A: Loose equality (==) compares two values for equality after
type coercion, while strict equality (===) compares two values
for equality without type coercion. It's generally recommended
to use strict equality whenever possible to avoid unexpected
behavior.

Q: What is the difference between an array and an object in


JavaScript?
A: An array is a collection of values that can be accessed using
numerical indices, while an object is a collection of key-value
pairs that can be accessed using keys. Arrays are useful for
storing ordered data, while objects are useful for storing data
that has named properties.

Q: What is the typeof operator in JavaScript?


A: The typeof operator is used to check the data type of a value
in JavaScript. For example, typeof 'hello' would return 'string',
while typeof 5 would return 'number'.

Code Exercises

Exercise 2.1: Basic Variable Declaration


Create a JavaScript program that declares a variable for each of
the following data types: string, number, boolean, array, and
object. Give each variable a descriptive name and assign it an
appropriate value. Then, use console.log() to print each variable
to the console.

Exercise 2.2: Concatenating Strings


Create a JavaScript program that declares a variable called
firstName and assigns it your first name as a string. Then,
declare another variable called lastName and assign it your last
name as a string. Finally, use string concatenation to print the
message "Hello, [your first name] [your last name]!" to the
console.

Page 42
Exercise 2.3: Declaring and Assigning Variables
Declare two variables, firstName and lastName, and assign
them your first and last name, respectively. Then, concatenate
the two variables together and print the result to the console.

Exercise 2.4: Converting a String to a Number


Declare a variable called stringNumber and assign it the value
'7'. Then, convert this value to a number and store it in a
variable called numberValue. Finally, add numberValue to the
number 5 and print the result to the console.

Exercise 2.5: Manipulating an Array


Declare an array called myArray that contains the values 1, 2,
and 3. Using array methods, add the value 4 to the end of the
array, remove the first value, and then print the resulting array
to the console.

Exercise 2.6: Converting Between Data Types


Declare a variable called myBoolean and assign it the value
true. Then, convert this value to a string and store it in a
variable called stringBoolean. Finally, print both the original
boolean value and the converted string value to the console.

Exercise 2.7: Complex Data Type Manipulation


Declare an object called myObject that contains the following
key-value pairs:

● name: a string with your name


● age: a number with your age
● hobbies: an array containing at least three of your
hobbies

Then, print the value of the second hobby in the array to the
console, and add a new key-value pair to the object called
occupation with your current or desired occupation. Finally,
print the entire object to the console.

Page 43
Section 3: Control Flow and Loops

Introduction
Welcome to Section 3 of the JavaScript Workbook! In this
section, we'll be covering control flow and loops, two essential
concepts in programming.

Control flow refers to the order in which statements are


executed in a program. Often, you'll want your program to
behave differently depending on certain conditions, and that's
where conditional statements come in. We'll be covering if/else
statements and switch/case statements, two ways of
controlling the flow of your program based on different
conditions.

Loops are another important part of control flow in JavaScript.


Loops allow you to repeat a block of code multiple times,
without having to write the same code over and over again.
We'll be covering for, while, and do/while loops, as well as loop
control statements like break and continue.

By the end of this section, you'll be able to write programs that


can make decisions and repeat tasks as many times as
necessary. So get ready to flex those coding muscles, and let's
dive into the world of control flow and loops in JavaScript!

Conditional Statements
In programming, we often need our programs to make
decisions based on certain conditions. That's where conditional
statements come in. In this section, we'll be covering two types
of conditional statements in JavaScript: if/else statements and
switch/case statements.

Page 44
If/Else Statements
If/else statements are a fundamental part of programming, and
they allow your program to execute different code blocks
depending on whether a certain condition is true or false.
Here's an example:

let myNumber = 10;

if (myNumber > 0) {
console.log('myNumber is positive');
} else {
console.log('myNumber is negative or zero');
}

In this example, if myNumber is greater than 0, the program


will print 'myNumber is positive' to the console. Otherwise, it
will print 'myNumber is negative or zero'.

You can also use else if statements to check for multiple


conditions:

let myNumber = 10;

if (myNumber > 0) {
console.log('myNumber is positive');
} else if (myNumber < 0) {
console.log('myNumber is negative');
} else {
console.log('myNumber is zero');
}

In this example, if myNumber is greater than 0, the program


will print 'myNumber is positive' to the console. If it's less than
0, it will print 'myNumber is negative'. Otherwise, it will print
'myNumber is zero'.

Page 45
Switch/Case Statements
Switch/case statements are another way of controlling the flow
of your program based on different conditions. They're often
used when you have multiple conditions to check. Here's an
example:

let dayOfWeek = 'Monday';

switch (dayOfWeek) {
case 'Monday':
console.log('It\'s Monday!');
break;
case 'Tuesday':
console.log('It\'s Tuesday!');
break;
case 'Wednesday':
console.log('It\'s Wednesday!');
break;
default:
console.log('It\'s some other day!');
}

In this example, the program will print a different message to


the console depending on the value of dayOfWeek. If
dayOfWeek is 'Monday', it will print 'It's Monday!'. If it's 'Tuesday',
it will print 'It's Tuesday!', and so on. If dayOfWeek doesn't
match any of the cases, it will print 'It's some other day!'.

In this example, the program will print a different message to


the console depending on the value of dayOfWeek. If
dayOfWeek is 'Monday', it will print 'It's Monday!'. If it's 'Tuesday',
it will print 'It's Tuesday!', and so on. If dayOfWeek doesn't
match any of the cases, it will print 'It's some other day!'.

Page 46
The prompt() Function
The prompt() function is a built-in function in JavaScript that
allows you to ask the user for input via a pop-up window. Here's
an example of how to use the prompt() function to ask the user
for their name:

let name = prompt("What is your name?");

In this example, the prompt() function displays a dialog box


with the message "What is your name?" The user can then
type in their name and click "OK" or press Enter to submit their
answer. The prompt() function returns the user's input as a
string, which is then stored in the name variable.

In JavaScript, the prompt() function is often used to get input


from the user for a variety of purposes, such as collecting user
data or asking for confirmation before performing an action. It
can be a useful tool when creating interactive programs and
applications.

Keep in mind that the prompt() function always returns a


string, so you may need to convert the input to a number or
other data type depending on what you're doing with it.

Code Exercises
Exercise 3.1: Odd or Even (with Modulus)
Write a program that asks the user for a number and checks
whether it's odd or even. If the number is even, the program
should print "The number is even." If it's odd, the program
should print "The number is odd." Use an if/else statement to
accomplish this, and don't forget about the modulus operator
(%), which can help you determine whether a number is even
or odd.

Page 47
Exercise 3.2: Grade Converter
Write a program that asks the user for a grade (a number
between 0 and 100) and converts it to a letter grade using the
following scale:

90-100: A
80-89: B
70-79: C
60-69: D
Below 60: F
Use a switch/case statement to accomplish this.

Iteration Statements (for, while, do/while)


In JavaScript, iteration statements are used to execute a block
of code repeatedly. There are three types of iteration
statements: for, while, and do/while. Each type has its own
syntax and use cases, but they all serve the same basic
purpose: to repeat a block of code until a certain condition is
met.

The for Loop


The for loop is the most commonly used iteration statement in
JavaScript. It allows you to execute a block of code a specified
number of times. Here's an example:

for (let i = 0; i < 5; i++) {


console.log(i);
}

In this example, the for loop will execute the block of code
inside the curly braces five times. The loop starts with i equal to
0, and then increments i by 1 on each iteration until i reaches 4.
The output of this code will be:

Page 48
0
1
2
3
4

The while Loop


The while loop is used to execute a block of code as long as a
specified condition is true. Here's an example:

let i = 0;
while (i < 5) {
console.log(i);
i++;
}

In this example, the while loop will execute the block of code
inside the curly braces as long as i is less than 5. The loop starts
with i equal to 0, and then increments i by 1 on each iteration
until i reaches 4. The output of this code will be:

0
1
2
3
4

The do/while Loop


The do/while loop is similar to the while loop, but the block of
code inside the curly braces is always executed at least once.
Here's an example:

Page 49
let i = 0;
do {
console.log(i);
i++;
} while (i < 5);

In this example, the do/while loop will execute the block of


code inside the curly braces at least once, and then continue to
execute it as long as i is less than 5. The loop starts with i equal
to 0, and then increments i by 1 on each iteration until i reaches
4. The output of this code will also be:

0
1
2
3
4

Choosing the Right Loop


Each type of loop has its own strengths and weaknesses, so it's
important to choose the right one for the task at hand. The for
loop is best for situations where you know exactly how many
times you need to repeat a block of code. The while loop is best
for situations where you need to repeat a block of code as long
as a certain condition is true, but you don't know how many
times the block of code will need to be executed. The do/while
loop is best for situations where you need to execute a block of
code at least once, and then continue to execute it as long as a
certain condition is true.

Iteration statements are a powerful tool in JavaScript that allow


you to execute a block of code repeatedly. Whether you're
using a for loop, a while loop, or a do/while loop, it's important

Page 50
to understand the strengths and weaknesses of each type of
loop so you can choose the right one for the task at hand. In
the next section, we'll cover loop control statements that allow
you to modify the behavior of loops and make them more
powerful.

Code Exercises
To complete these exercises you’re going to need to make
JavaScript do a bit of math:

Math.floor() is a method that takes a decimal number and


rounds it down to the nearest whole number. It's often used in
combination with Math.random() to generate a random
integer between a given range. For example,
Math.floor(Math.random() * 10) will generate a random integer
between 0 and 9.

Math.random() is a method that returns a random decimal


number between 0 and 1. It's often used in combination with
Math.floor() to generate a random integer.

let randomNumber = Math.floor(Math.random() * 10) + 1;


console.log(randomNumber);

In this example, Math.random() generates a random decimal


number between 0 and 1, which is then multiplied by 10 to give
us a random number between 0 and 10. We then use
Math.floor() to round down this number to the nearest whole
number, which gives us a random integer between 0 and 9.
Finally, we add 1 to this number to get a random integer
between 1 and 10. The randomNumber variable stores this
value, which we then log to the console using console.log().

Exercise 3.3: For Loop

Page 51
Write a for loop that prints out 5 random numbers between 1
and 10.

Exercise 3.4: While Loop


Write a while loop that prints out random numbers between 1
and 10 until the number 7 is generated. Once the number 7 is
generated, the loop should end and the number 7 should also
be printed out.

Exercise 3.5: Do/While Loop


Write a do/while loop that prompts the user to enter a number
until they enter a number that is divisible by 5. Then, print out
the number they entered.

Exercise 3.6: Fizz Buzz


Write a for loop that prints out the numbers from 1 to 100. For
numbers that are divisible by 3, print "Fizz" instead of the
number. For numbers that are divisible by 5, print "Buzz"
instead of the number. For numbers that are divisible by both 3
and 5, print "FizzBuzz" instead of the number.

Loop control statements (break, continue)


Sometimes, we need more control over loops than just starting
and stopping them. That's where loop control statements like
break and continue come in. In this section, we'll explore how
to use these statements to give us more control over our loops.

The break statement


The break statement is used to immediately exit a loop. When
the interpreter encounters a break statement in a loop, it stops
executing the loop and moves on to the next statement after
the loop. Here's an example:

for (let i = 1; i <= 10; i++) {

Page 52
if (i === 5) {
break;
}
console.log(i);
}

In this example, the loop runs for 5 iterations, and when i


reaches 5, the break statement is executed, causing the loop to
immediately stop. As a result, only the numbers 1 through 4 are
logged to the console.

The continue statement


The continue statement is used to skip over one iteration of a
loop. When the interpreter encounters a continue statement in
a loop, it skips over the current iteration and moves on to the
next iteration of the loop. Here's an example:

for (let i = 1; i <= 10; i++) {


if (i % 2 === 0) {
continue;
}
console.log(i);
}

In this example, the loop runs for 10 iterations, but on


even-numbered iterations (when i is divisible by 2), the
continue statement is executed, causing the loop to skip over
that iteration. As a result, only the odd numbers 1, 3, 5, 7, and 9
are logged to the console.

Combining break and continue


You can also use break and continue together in more complex
loops to control their behavior. Here's an example:

Page 53
for (let i = 1; i <= 10; i++) {
if (i % 2 === 0) {
continue;
}
if (i === 7) {
break;
}
console.log(i);
}

In this example, the loop runs for 10 iterations, but on


even-numbered iterations (when i is divisible by 2), the
continue statement is executed, causing the loop to skip over
that iteration. If i ever reaches 7, the break statement is
executed, causing the loop to immediately stop. As a result, the
odd numbers 1, 3, and 5 are logged to the console.

Overall, break and continue statements can be extremely


useful in controlling the flow of loops, especially when working
with more complex loops that require more control.

Coding Exercises
Exercise 3.7: Find the first even number
Write a program that uses a for loop to find the first even
number in an array of integers. Once you've found the first
even number, use the break statement to exit the loop and log
the even number to the console.

Exercise 3.8: Skip over negative numbers


Write a program that uses a for loop to iterate over an array of
integers. For each integer in the array, check if it is negative. If it
is, use the continue statement to skip over that iteration of the
loop. If it is not negative, log the integer to the console.

Page 54
Critical Points
Conditional Statements:

● Allow your program to make decisions based on certain


conditions.
● The most common types are if/else statements and
switch/case statements.
● If/else statements evaluate a condition and execute
code based on whether that condition is true or false.
● Switch/case statements provide an alternative way to
evaluate multiple conditions and execute different code
based on the value of a variable.

Iteration Statements:
● Allow you to repeat a block of code until a certain
condition is met.
● The most common types are for loops, while loops, and
do/while loops.
● For loops are used when you know the number of times
you want to repeat a block of code.
● While loops are used when you want to repeat a block
of code until a certain condition is met, and you don't
know how many times you'll need to repeat it.
● Do/while loops are similar to while loops, but the block
of code is executed at least once even if the condition is
initially false.

Loop Control Statements:


● Allow you to exit or skip a loop based on certain
conditions.
● The two most common types are break statements and
continue statements.
● Break statements are used to completely exit a loop.
● Continue statements are used to skip over an iteration
of a loop and move on to the next iteration

Page 55
The FAQ
Q: What is the difference between a for loop and a while loop?
A: For loops are used when you know the exact number of
times you want to repeat a block of code. While loops, on the
other hand, are used when you want to repeat a block of code
until a certain condition is met, and you may not know the
exact number of times you'll need to repeat it.

Q: What is the purpose of loop control statements like break


and continue?
A: Break statements allow you to completely exit a loop, while
continue statements allow you to skip over an iteration of a
loop and move on to the next iteration.

Q: When should I use an if/else statement versus a switch/case


statement?
A: If/else statements are useful when you need to evaluate a
single condition and execute different code based on whether
that condition is true or false. Switch/case statements are
useful when you need to evaluate multiple conditions and
execute different code based on the value of a variable.

Q: How do I prevent an infinite loop from occurring?


A: To prevent an infinite loop from occurring, make sure that
your loop condition will eventually evaluate to false. You can
also include a break statement within your loop to exit it under
certain conditions.

Q: Can I use a loop to iterate over an object in JavaScript?


A: No, you cannot use a loop to iterate over an object in
JavaScript. Instead, you can use a for...in loop to iterate over the
keys of an object, or you can use methods like Object.values()
or Object.entries() to iterate over the values or key-value pairs of
an object.

Page 56
Section 4: JavaScript Functions

Introduction
Welcome to Section 4, where we'll dive into the wonderful
world of functions in JavaScript. Functions are an essential part
of any programming language and can be incredibly powerful
tools for writing efficient and reusable code.

In this section, we'll cover everything you need to know about


functions in JavaScript, starting with the basics of declaring
and calling functions. We'll also explore how to work with
function parameters and arguments, which allow us to pass
data into functions and make them more flexible.

Finally, we'll explore function scope and closures, which can be


a bit more advanced but are critical to understanding how
functions work in JavaScript. We'll cover how to create closures,
which are functions that remember the values of variables
even after they have been returned, and how to use them to
write more powerful and flexible code.

So whether you're a seasoned developer or just starting out,


get ready to dive into the world of functions in JavaScript. We
promise to make it fun and engaging, with plenty of code
examples and nerdy jokes along the way.

Declaring and Calling Functions


Functions are like superheroes in the programming world.
They have the power to take on any task and make your code
more efficient and reusable. But before we can start using
functions to save the day, we need to understand how to
declare and call them in JavaScript.

Page 57
Declaring Functions
Functions are like superheroes in the programming world.
They have the power to take on any task and make your code
more efficient and reusable. But before we can start using
functions to save the day, we need to understand how to
declare and call them in JavaScript.

Declaring a function is like creating a blueprint for a task that


needs to be performed. It's where we define what the function
does, what arguments it takes, and what it returns. Here's what
a basic function declaration looks like:

function greet(name) {
console.log("Hello, " + name + "!");
}

In this example, we've declared a function called greet that


takes one argument called name. The function uses
console.log() to output a greeting to the console.

Calling Functions
Now that we've declared our function, we can call it to execute
the code inside it. Here's how we would call our greet function:

greet("Bob");
// Output: Hello, Bob!

In this example, we're passing the string "Bob" as an argument


to our greet function. The function then uses this argument to
output a personalized greeting to the console.

Page 58
Function Return Values
So far, our greet function has been using console.log() to
output a greeting to the console. But what if we want our
function to return a value that we can use elsewhere in our
code?

function add(a, b) {
return a + b;
}

In this example, we've declared a function called add that takes


two arguments called a and b. The function uses the return
keyword to return the sum of a and b.

To use the value returned by this function, we can assign it to a


variable:

var sum = add(2, 3);


console.log(sum);
// Output: 5

In this example, we're calling our add function with arguments


2 and 3, and assigning the returned value to a variable called
sum. We then use console.log() to output the value of sum to
the console, which should be 5.

And there you have it! That's the basics of declaring and calling
functions in JavaScript. Keep these concepts in mind as we
move on to the more advanced topics in the following sections.

Function Parameters and Arguments


Functions are a powerful tool in JavaScript, allowing us to
encapsulate and reuse code. One important aspect of
functions is the ability to pass arguments, or inputs, into a

Page 59
function. In this section, we'll explore how to define and use
function parameters and arguments.

Defining Function Parameters


A function parameter is a variable that is defined as part of the
function declaration, and is used to accept arguments when
the function is called. The syntax for defining function
parameters is simple - simply include a list of parameter names
inside the function parentheses, separated by commas. Here's
an example:

function greet(name, age) {


console.log(`Hello ${name}, you are ${age} years
old!`);
}

In this example, name and age are the function parameters.

Using Function Arguments


When a function is called, arguments can be passed into the
function, which are then assigned to the function parameters.
The number of arguments must match the number of
function parameters, and the order of the arguments matters.
Here's an example:

greet('Alice', 25);
// Output: Hello Alice, you are 25 years old!

In this example, the string 'Alice' is passed as the first


argument, which is assigned to the name parameter. The
number 25 is passed as the second argument, which is
assigned to the age parameter.

Page 60
Default Parameter Values
In some cases, you may want to provide a default value for a
function parameter in case no argument is provided. This can
be done by using the assignment operator (=) when defining
the function parameter. Here's an example:

function greet(name = 'friend', age = 0) {


console.log(`Hello ${name}, you are ${age} years
old!`);
}

In this example, if no argument is provided for name, the


default value of 'friend' will be used. If no argument is provided
for age, the default value of 0 will be used.

Rest Parameters
Sometimes, you may want to define a function that can accept
a variable number of arguments. This can be done using the
rest parameter syntax, which allows you to define a parameter
that will receive an array of all remaining arguments passed to
the function. Here's an example:

function sum(...numbers) {
let result = 0;
for (let i = 0; i < numbers.length; i++) {
result += numbers[i];
}
console.log(`The sum is ${result}`);
}

In this example, the sum function can accept any number of


arguments, which will be combined into an array called
numbers. The function then iterates over this array and adds
up all the values.

Page 61
Function parameters and arguments are an essential part of
JavaScript programming. By defining and using function
parameters, you can create reusable and flexible functions that
can be used in a variety of contexts.

Code Exercises
Exercise 4.1: Calculator
Write a function called calculator that takes in two numbers
and a string representing an operation (+, -, *, /) and returns the
result of that operation. Use a switch statement to handle the
different operations.

Exercise 4.2: Calculate the sum of two arrays


Write a function called arraySum that takes two arrays of
numbers as parameters and returns the sum of all the
numbers in both arrays. Hint: You can use a loop to iterate over
the elements in each array and add them together.

Exercise 4.3: Find the Longest Word


Write a function called findLongestWord that takes in a string
and returns the length of the longest word in the string.
Assume that the string only contains letters and spaces. Hint:
use the split() method to split the string into an array of words.

Exercise 4.4: Reverse a String


Write a function called reverseString that takes in a string and
returns the reversed version of the string. Hint: use a loop to
iterate over the string backwards.

Exercise 4.5: Count Vowels


Write a function called countVowels that takes in a string and
returns the number of vowels (a, e, i, o, u) in the string. Ignore
case, so both "a" and "A" should be counted as vowels.

Page 62
Function expressions and arrow functions
So far, we've been declaring our functions using the function
keyword followed by the function name and the function body
in curly braces. However, there are other ways to declare
functions in JavaScript that can be more concise and easier to
read.

Function Expressions
A function expression is a way of defining a function as a
variable assignment. The variable can then be called like a
function. Here's an example:

const add = function(a, b) {


return a + b;
}

console.log(add(2, 3)); // Output: 5

In this example, we're defining a function called add and


assigning it to a variable using a const declaration. We can
then call the add function using the variable name.

Arrow Functions
Arrow functions are a shorthand way of declaring functions
that were introduced in ECMAScript 6 (ES6). They use a
different syntax and have some differences in how this is
handled. Here's an example:

const add = (a, b) => {


return a + b;
}

console.log(add(2, 3)); // Output: 5

Page 63
In this example, we're declaring the add function using the
arrow function syntax. The function parameters are enclosed in
parentheses, followed by the arrow => and then the function
body in curly braces.

Arrow functions have some shorthand syntax when there is


only one parameter and one line of code in the function body:

const square = num => num * num;

console.log(square(4)); // Output: 16

Here we're defining a function called square that takes one


parameter using arrow function shorthand. Since there is only
one line of code in the function body, we don't need to use
curly braces and the return keyword.

Function expressions and arrow functions can be more concise


and easier to read than traditional function declarations. They
are also useful in certain situations where you need to pass a
function as an argument to another function. With this
knowledge, you can start to write more efficient and elegant
code.

Code Exercise
Exercises 4.6: Rewrite as Arrow Functions
Rewrite the following traditional JavaScript functions asarrow
functions.

Function A
function multiplyByTwo(num) {
return num * 2;
}

Page 64
Function B
function addNumbers(num1, num2) {
return num1 + num2;
}

Function C
function greeting(name) {
return "Hello, " + name + "!";
}

Function Scope and Closures


Functions are not only useful for modularizing code and
making it more readable, but they also play a critical role in
managing the scope of variables in JavaScript. In this chapter,
we'll explore how variable scope works in functions, as well as
the concept of closures.

Function Scope
When you declare a variable inside a function, it's only
accessible inside that function. This is called function scope. It
means that the variable is only defined within the function's
curly braces, and any attempts to access it from outside the
function will result in an error.

Let's take a look at an example:


function myFunction() {
var myVar = "Hello";
console.log(myVar);
}

Page 65
myFunction();
console.log(myVar);

In this example, myVar is declared inside the myFunction


function, which means it has function scope. When we call
myFunction, it logs "Hello" to the console because myVar is
defined inside the function. However, when we try to log myVar
outside the function, we get an error because myVar is not
defined outside the function.

Global Scope
Variables declared outside of any function have global scope,
which means they can be accessed from anywhere in your
code, including inside functions. It's generally a good idea to
avoid using global variables as they can be accessed and
modified from anywhere in your code, which can lead to
unexpected bugs.

Let's take a look at an example:

var myGlobalVar = "Hello";

function myFunction() {
console.log(myGlobalVar);
}

myFunction();
console.log(myGlobalVar);

In this example, myGlobalVar is declared outside of any


function, which gives it global scope. When we call
myFunction, it logs "Hello" to the console because myGlobalVar
is accessible inside the function. When we log myGlobalVar
outside the function, we get "Hello" again because it's a global
variable.

Page 66
Closures
A closure is created when a function is defined inside another
function and has access to the outer function's variables. In
other words, the inner function "closes over" the variables of
the outer function. This allows us to create private variables and
functions that are not accessible from outside the outer
function.

Let's take a look at an example:


function outerFunction() {
var outerVar = "Hello";

function innerFunction() {
console.log(outerVar);
}

return innerFunction;
}

var myFunction = outerFunction();


myFunction();

In this example, outerFunction defines a variable outerVar and


a function innerFunction. innerFunction has access to outerVar
because it's defined inside outerFunction. When we call
outerFunction, it returns innerFunction. We assign the
returned function to myFunction and call it. When we call
myFunction, it logs "Hello" to the console because
innerFunction has access to outerVar.

By understanding function scope and closures, you can write


more maintainable and modular code. Let's move on to the
exercises to practice what we've learned.

Page 67
Code Exercises
Exercise 4.7 Calculator
Write a function called calculator that takes in two numbers
and a string representing an operation (+, -, *, /) and returns the
result of that operation. Use a switch statement to handle the
different operations.

Exercise 4.8: Calculate the sum of two arrays


Write a function called arraySum that takes two arrays of
numbers as parameters and returns the sum of all the
numbers in both arrays. Hint: You can use a loop to iterate over
the elements in each array and add them together.

Exercise 4.9: Find the Longest Word


Write a function called findLongestWord that takes in a string
and returns the length of the longest word in the string.
Assume that the string only contains letters and spaces. Hint:
use the split() method to split the string into an array of words.

Exercise 4.10: Reverse a String


Write a function called reverseString that takes in a string and
returns the reversed version of the string. Hint: use a loop to
iterate over the string backwards.

Critical Points
Functions
● A function is a reusable block of code that performs a
specific task.
● Functions are declared using the function keyword,
followed by the function name, and a set of parentheses
that can optionally contain parameters.
● To call a function, use the function name followed by
parentheses and any necessary arguments.
● Functions can return values using the return keyword.

Page 68
● Functions can be declared as function expressions,
which allow them to be assigned to variables, passed as
arguments to other functions, and used as return
values.
● Arrow functions are a shorthand syntax for declaring
function expressions.
● Functions have their own scope, meaning variables
declared within a function are only accessible within
that function.

Function Parameters and Arguments


● Function parameters are variables that are listed as part
of a function's definition.
● Function arguments are values passed into a function
when it is called.
● Functions can accept any number of parameters,
separated by commas.
● When calling a function with arguments, the values
passed in must match the number and order of the
function's parameters.
● Function parameters can have default values, which are
used when a value is not provided for that parameter.

Function Expressions and Arrow Functions


● Function expressions allow functions to be assigned to
variables, passed as arguments to other functions, and
used as return values.
● Arrow functions are a shorthand syntax for declaring
function expressions, and are especially useful for
writing concise, one-line functions.
● Arrow functions have a more concise syntax than
traditional function expressions, but may not be as
readable in all cases.
● Arrow functions do not have their own this keyword, but
instead inherit the this value of the enclosing context.

Function Scope and Closures

Page 69
● Functions have their own scope, meaning variables
declared within a function are only accessible within
that function.
● Variables declared outside of any function are said to
have global scope, and can be accessed from anywhere
in the code.
● Closures are created when a function is declared inside
another function, and the inner function has access to
the outer function's variables and parameters.
● Closures allow for powerful programming patterns such
as private variables and encapsulation, but can also lead
to memory leaks if not used carefully.

The FAQ
Q: How do I pass arguments to a function?
A: When you call a function, you can pass any number of
arguments by including them in the parentheses separated by
commas. For example, myFunction(1, "hello", true) would pass
the values 1, "hello", and true as arguments to the function.

Q: Can a function have multiple return statements?


A: Yes, a function can have multiple return statements, but only
one of them will be executed. When a return statement is
reached, the function immediately exits and returns the
specified value. Any code after the return statement will not be
executed.

Q: How do I define a function that takes no parameters?


A: To define a function that takes no parameters, simply omit
the parentheses in the function signature. For example,
function myFunction() { ... } would define a function with no
parameters.

Q: What is the difference between function declarations and


function expressions?

Page 70
A: Function declarations are defined using the function
keyword and are hoisted to the top of their scope. This means
they can be called before they are defined. Function
expressions, on the other hand, are defined as variables and are
not hoisted. They must be defined before they are called.

Q: What is a closure and why is it useful?


A: A closure is a function that has access to variables defined in
an outer function, even after that function has completed
execution. Closures are useful for maintaining private variables
and creating factory functions that can generate new functions
with specific behavior.

Page 71
Section 5: Working with Arrays
Arrays are one of the most fundamental data structures in
computer science, and they're a vital tool for any programmer.
In JavaScript, arrays can hold a mix of different types of data
and can be manipulated in a variety of ways.

We'll start by discussing how to declare and initialize arrays,


including multi-dimensional arrays. Then, we'll dive into the
most common array methods such as push, pop, shift, and
unshift, which allow us to add and remove elements from an
array. Finally, we'll explore the many ways to iterate over arrays,
including the forEach, map, filter, and reduce methods.

By the end of this chapter, you'll have a solid understanding of


arrays and be able to use them effectively in your JavaScript
programs. So, grab your coding hat and let's get started!

Declaring and initializing arrays


In this section, we will be diving into one of the most important
and commonly used data types in JavaScript - arrays. We will
start by exploring the basics of declaring and initializing arrays.

Declaring Arrays
Declaring an array in JavaScript is as simple as using the "let"
keyword followed by the array name and square brackets.
Arrays can hold a mixture of different data types including
strings, numbers, and even other arrays. Here's an example:

let myArray = ['apple', 'banana', 'orange'];

In the previous example we used “literal notation,” which is the


most commonly used method of declaring an array. There are
other methods as well.

Page 72
You can also use the new keyword to create an array. In this
case, you pass the elements of the array as arguments to the
Array constructor. This method is less common than the literal
notation, but it can be useful in certain situations.

let myArray = new Array(1, 2, 3, 4, 5);

You can also create an empty array by simply assigning an


empty set of square brackets to a variable. You can then add
elements to the array using one of the methods we'll discuss in
the next section.

No matter which method you choose to declare and initialize


your arrays, you can access and manipulate the elements of
the array using the array index, which starts at 0.

let myArray = [];

Initializing Arrays
Initializing an array is simply the process of adding values to it.
There are a couple of ways to do this in JavaScript. One way is
to use the square bracket notation to assign values to specific
indexes in the array. Here's an example:

let myArray = [];


myArray[0] = 'apple';
myArray[1] = 'banana';
myArray[2] = 'orange';

Another way to initialize an array is to list out the values in the


square brackets during the declaration. Here's an example:

Page 73
let myArray = ['apple', 'banana', 'orange'];

It's important to note that JavaScript arrays are dynamic and


can be modified after they have been initialized. This means
you can add or remove elements from an array at any time.

Accessing Array Members


You can access individual members of an array using bracket
notation and the index of the element you want to access.
Remember that array indices are zero-based, so the first
element of an array is at index 0, the second element is at
index 1, and so on.

const myArray = [1, 2, 3];


console.log(myArray[0]); // outputs 1
console.log(myArray[1]); // outputs 2
console.log(myArray[2]); // outputs 3

Addressing Non-Existent Array Members


If you try to access an array member that doesn't exist, you'll
get “undefined” as the result:

const myArray = [1, 2, 3];


console.log(myArray[4]); // outputs undefined

Keep in mind that trying to access a non-existent array


member will not throw an error, but will simply return
undefined. If you try to modify a non-existent array member,
you will add a new element to the array at that index:

const myArray = [1, 2, 3];


myArray[4] = 4;
console.log(myArray); // outputs [1, 2, 3, undefined,

Page 74
4]

Multidimensional Arrays
In addition to single-dimensional arrays, JavaScript also
supports multidimensional arrays. A multidimensional array is
essentially an array of arrays. Here's an example:

const grid = [
[1, 2, 3],
[4, 5, 6],
[7, 8, 9]
];

In this example, grid is a 3x3 table of data. The first element of


grid is an array containing the numbers 1, 2, and 3. The second
element is an array containing the numbers 4, 5, and 6. The
third element is an array containing the numbers 7, 8, and 9.

To access an element of a multidimensional array, you need to


provide an index for each dimension of the array. For example,
to access the element in the second row and third column of
the grid array above, you would use the following syntax:

const element = grid[1][2]; // element = 6

In this example, the first index (1) refers to the second row of
the grid array, and the second index (2) refers to the third
column of that row.

You can modify elements of a multidimensional array just like


you would with a one-dimensional array. Simply provide the
appropriate indices to access the desired element. For

Page 75
example, to change the value of the element in the second row
and third column of the grid array, you would use the following
syntax:

grid[1][2] = 42;

After this line of code is executed, the value of the element in


the second row and third column of the grid array will be 42.

Array methods (push, pop, shift, unshift,


etc.)
Arrays in JavaScript come with a variety of built-in methods
that make it easier to manipulate the contents of an array.
These methods include push(), pop(), shift(), unshift(), splice(),
and more. Let's take a closer look at each of them.

Adding Elements with push() and unshift()


Two of the most commonly used array methods for adding
elements to an array are push() and unshift(). push() adds an
element to the end of an array, while unshift() adds an element
to the beginning of an array.

const fruits = ['apple', 'banana', 'orange'];


fruits.push('pear');
console.log(fruits); // output: ['apple', 'banana',
'orange', 'pear']

fruits.unshift('grape');
console.log(fruits); // output: ['grape', 'apple',
'banana', 'orange', 'pear']

Page 76
Removing Elements with pop() and shift()
pop() and shift() are the counterpart to push() and unshift(),
respectively. They remove elements from the end and
beginning of an array.

const fruits = ['apple', 'banana', 'orange', 'pear'];


fruits.pop();
console.log(fruits); // output: ['apple', 'banana',
'orange']

fruits.shift();
console.log(fruits); // output: ['banana', 'orange']

Modifying Elements in an Array with splice()


The splice() method is used to modify an array by adding or
removing elements. It takes three arguments: the index at
which to start modifying the array, the number of elements to
remove, and any new elements to add.

const fruits = ['apple', 'banana', 'orange', 'pear'];


fruits.splice(1, 1, 'mango', 'kiwi');
console.log(fruits); // output: ['apple', 'mango',
'kiwi', 'orange', 'pear']

Here are a few more methods you can use with arrays that you
may find useful:

Finding Elements in an Array with indexOf()


The indexOf() method is used to find the index of a specified
element in an array. If the element is not found in the array, it
returns -1.

const fruits = ['apple', 'banana', 'orange', 'pear'];

Page 77
console.log(fruits.indexOf('banana')); // output: 1
console.log(fruits.indexOf('grape')); // output: -1

Checking If an Array Includes an Element with


includes()
The includes() method is used to check if an array includes a
specified element. It returns true if the element is found in the
array, and false otherwise.

const fruits = ['apple', 'banana', 'orange', 'pear'];


console.log(fruits.includes('banana')); // output: true
console.log(fruits.includes('grape')); // output: false

The slice() method


The slice() method returns a shallow copy of a portion of an
array into a new array object. The original array will not be
modified. Here's an example:

const colors = ['red', 'green', 'blue', 'yellow',


'purple'];
const newColors = colors.slice(1, 4); // ['green',
'blue', 'yellow']
console.log(colors); // ['red', 'green', 'blue',
'yellow', 'purple']
console.log(newColors); // ['green', 'blue', 'yellow']

The splice() method


The splice() method is used to add or remove elements from an
array. Here's an example:

Page 78
const colors = ['red', 'green', 'blue', 'yellow',
'purple'];
const removedColors = colors.splice(1, 2, 'orange',
'pink'); // ['green', 'blue']
console.log(colors); // ['red', 'orange', 'pink',
'yellow', 'purple']
console.log(removedColors); // ['green', 'blue']

In this example, we remove two elements starting from index 1


(green and blue) and replace them with orange and pink. The
splice() method also returns the removed elements as a new
array.

The concat() method


The concat() method is used to merge two or more arrays into
a new array. Here's an example:

const primaryColors = ['red', 'green', 'blue'];


const secondaryColors = ['orange', 'purple', 'yellow'];
const allColors =
primaryColors.concat(secondaryColors);
console.log(allColors); // ['red', 'green', 'blue',
'orange', 'purple', 'yellow']

In this example, we merge two arrays into a new array using


the concat() method. The original arrays are not modified.

Converting Arrays to Strings and Vice Versa

The join() method


The join() method converts an array to a string. It concatenates
all the elements of an array into a single string and returns the
result. By default, the elements are separated by a comma, but

Page 79
you can specify a different separator as an argument to the
method.

Here's an example:
const fruits = ['apple', 'banana', 'cherry'];
const fruitsString = fruits.join(', ');

console.log(fruitsString); // Output: "apple, banana,


cherry"

In this example, we called the join() method on the fruits array


with a comma and a space as the separator. The resulting
string is "apple, banana, cherry".

The split() method


The split() method does the opposite of join(). It converts a
string to an array by breaking it up into an array of substrings.
You can specify the separator character or substring as an
argument to the method. If no separator is specified, the string
is split into an array of individual characters.

Here's an example:
const fruitsString = 'apple, banana, cherry';
const fruitsArray = fruitsString.split(', ');

console.log(fruitsArray); // Output: ["apple",


"banana", "cherry"]

In this example, we called the split() method on the fruitsString


string with a comma and a space as the separator. The
resulting array is ["apple", "banana", "cherry"].

Page 80
Iterating Through Arrays with For and
While Loops
In addition to declaring and initializing arrays, you will often
need to iterate over the elements in an array to perform some
operation on each one. Two common ways to do this are with
for and while loops. In this section, we will explore how to use
these loops to iterate over arrays, perform operations on the
elements, and store the results in a new array. This is a
fundamental concept in programming and an essential skill for
any JavaScript developer. Let's dive in!

Iterating Through Arrays with a For Loop


The basic structure of a for loop is as follows:

for (let i = 0; i < array.length; i++) {


// do something with array[i]
}

This loop initializes a counter variable i to 0, tests whether i is


less than the length of the array, and increments i after each
iteration. The loop body performs some action on the element
of the array at index i.

For example, to print all the elements of an array using a for


loop, you can do:

const colors = ['red', 'green', 'blue'];


for (let i = 0; i < colors.length; i++) {
console.log(colors[i]);
}

This loop will print:

Page 81
red
green
blue

Iterating Through Arrays with a While Loop


A while loop is similar to a for loop, but it uses a condition
instead of a counter to control the loop:

let i = 0;
while (i < array.length) {
// do something with array[i]
i++;
}

This loop initializes a variable i to 0, and repeats the loop body


as long as i is less than the length of the array. The loop body
performs some action on the element of the array at index i,
and increments i after each iteration.

For example, to find the first negative number in an array using


a while loop, you can do:

const numbers = [1, 2, -3, 4, -5, 6];


let i = 0;
while (i < numbers.length && numbers[i] >= 0) {
i++;
}
if (i < numbers.length) {
console.log(`The first negative number is
${numbers[i]}`);
} else {
console.log('There is no negative number in the
array');
}

Page 82
This loop will print:

The first negative number is -3

The ability to loop through arrays and manipulate their values


is essential for creating dynamic web applications. In the next
section, we'll explore more advanced methods for iterating over
arrays, such as map() and filter().

Iterating over arrays (forEach, map, filter,


reduce)
Iterating over arrays can be a powerful tool for manipulating
and analyzing data. In this section, we'll explore four methods
of iterating over arrays: forEach(), map(), filter(), and reduce().

forEach()
The forEach() method is used to execute a function for each
element in an array. The syntax for forEach() is as follows:

array.forEach(function(currentValue, index, array) {


// code to execute for each element
});

The currentValue parameter represents the current element


being processed in the array. The index parameter represents
the index of the current element. The array parameter
represents the array being traversed.

For example, let's say we have an array of numbers and we


want to print each number to the console:

const numbers = [1, 2, 3, 4, 5];

Page 83
numbers.forEach(function(number) {
console.log(number);
});

This code will output the following to the console:


1
2
3
4
5

map()
The map() method is used to create a new array with the
results of calling a function for each element in an array. The
syntax for map() is as follows:

const newArray = array.map(function(currentValue,


index, array) {
// code to execute for each element
return result;
});

The currentValue parameter represents the current element


being processed in the array. The index parameter represents
the index of the current element. The array parameter
represents the array being traversed. The function returns a
value that will be added to the new array.

For example, let's say we have an array of numbers and we


want to create a new array with each number doubled:

const numbers = [1, 2, 3, 4, 5];

const doubledNumbers = numbers.map(function(number) {

Page 84
return number * 2;
});

console.log(doubledNumbers);

This code will output the following to the console:

[2, 4, 6, 8, 10]

filter()
The filter() method is used to create a new array with all
elements that pass a certain condition. The syntax for filter() is
as follows:

const newArray = array.filter(function(currentValue,


index, array) {
// condition to test for each element
return true or false;
});

The currentValue parameter represents the current element


being processed in the array. The index parameter represents
the index of the current element. The array parameter
represents the array being traversed. The function returns a
Boolean value that determines whether the element should be
added to the new array.

For example, let's say we have an array of numbers and we


want to create a new array with only the even numbers:

const numbers = [1, 2, 3, 4, 5];

const evenNumbers = numbers.filter(function(number) {


return number % 2 === 0;

Page 85
});

console.log(evenNumbers);

This code will output the following to the console:

[2, 4]

Code Exercises
Exercise 5.1: Array Practice
In this lab, you will practice declaring and initializing arrays, as
well as accessing their elements.

1. Declare a new array called myArray and initialize it with


the values [1, 2, 3]
2. Use the push() method to add the values 4 and 5 to the
end of the array
3. Use bracket notation to access the value 2 in the array
and assign it to a new variable called x
4. Use a for loop to iterate through the array and print
each value to the console

Exercise 5.2: Array Methods


In this lab, you will practice using array methods to modify and
manipulate arrays.

1. Declare a new array called fruits and initialize it with the


values ['apple', 'banana', 'cherry']
2. Use the push() method to add the value 'orange' to the
end of the array
3. Use the pop() method to remove the last value from the
array

Page 86
4. Use the unshift() method to add the value 'pear' to the
beginning of the array
5. Use the shift() method to remove the first value from
the array
6. Use the splice() method to remove the value 'banana'
from the array
7. Use the slice() method to create a new array called
newFruits that contains the values 'apple' and 'cherry'

Exercise 5.3: Array Iteration


In this lab, you will practice iterating over arrays using the
forEach() method.

1. Declare a new array called numbers and initialize it with


the values [1, 2, 3, 4, 5]
2. Use the forEach() method to iterate over the array and
print each value to the console

Exercise 5.4: Array Mapping


In this lab, you will practice using the map() method to create a
new array based on an existing array.

1. Declare a new array called numbers and initialize it with


the values [1, 2, 3, 4, 5]
2. Use the map() method to create a new array called
squares that contains the squares of each value in the
numbers array
3. Print the squares array to the console

Exercise 5.5: Array Filtering


In this lab, you will practice using the filter() method to create a
new array based on a condition.

1. Declare a new array called numbers and initialize it with


the values [1, 2, 3, 4, 5]

Page 87
2. Use the filter() method to create a new array called
evens that contains only the even numbers from the
numbers array
3. Print the evens array to the console

Exercise 5.6: Random Quote Generator


In this project, you will create a random quote generator using
arrays in JavaScript. The project will display a random quote on
a webpage each time the user clicks a button. You will also
style the webpage using HTML and CSS.

Requirements:

● Create an array of at least 10 quotes


● When the user clicks a button, the program should
randomly select one quote from the array and display it
on the webpage
● Style the webpage using HTML and CSS to create an
appealing and user-friendly design
● Include a button to generate a new random quote

Note: This lab uses a few elements of JavaScript that you


haven’t learned yet– Do some research and see if you can stil
make it work!

Critical Points
Declaring and initializing arrays:
● Arrays are a type of object that can hold multiple values
of different types.
● Use the square bracket notation to declare an array and
initialize it with values.

Declaring Arrays:
● Declare a new array using the square bracket notation.
● Arrays can contain values of any data type.

Page 88
● Use the length property to find the number of elements
in an array.

Initializing Arrays:
● Initialize an array by providing a comma-separated list
of values inside the square brackets.
● Arrays can also be initialized with values using the new
Array() constructor.

Accessing Array Members:


● Use the square bracket notation to access individual
elements of an array.
● The index of the first element is 0, and the index of the
last element is length-1.

Multidimensional Arrays:
● A multidimensional array is an array of arrays.
● Use nested square brackets to access elements of a
multidimensional array.

Array methods (push, pop, shift, unshift, etc.):


● Array methods provide useful functionality for working
with arrays.
● push() adds an element to the end of the array.
● pop() removes the last element from the array.
● shift() removes the first element from the array.
● unshift() adds an element to the beginning of the array.

Iterating Over Arrays with For and While Loops:


● Use a for loop or a while loop to iterate over the
elements of an array.
● Use the length property to determine the number of
elements in an array.

Iterating over arrays (forEach, map, filter, reduce):


● Use the forEach() method to execute a function for each
element in an array.

Page 89
● Use the map() method to create a new array based on
an existing array.
● Use the filter() method to create a new array based on a
condition.
● Use the reduce() method to apply a function to each
element of an array and return a single value.

The FAQ
Q: What is an array?
A: An array is a special variable in JavaScript that can hold
multiple values.

Q: How do I declare an array?


A: To declare an array, use the following syntax: `let myArray =
[];`. This creates an empty array.

Q: How do I add values to an array?


A: To add values to an array, you can use the push() method. For
example: `myArray.push(1);` will add the value 1 to the end of
the array.

Q: How do I access values in an array?


A: To access values in an array, use bracket notation. For
example: `let x = myArray[0];` will assign the value at index 0 of
the array to the variable x.

Q: What are multidimensional arrays?


A: Multidimensional arrays are arrays that contain other arrays.
They allow you to store and manipulate more complex data
structures.

Q: How do I use array methods to modify an array?


A: Array methods like push(), pop(), shift(), and unshift() can be
used to add or remove values from an array. The splice()
method can be used to remove or insert values at a specific

Page 90
index. The slice() method can be used to create a new array
that contains a subset of the values in the original array.

Q: How do I iterate over an array?


A: There are several ways to iterate over an array in JavaScript.
You can use a for loop or a while loop to loop through each
value in the array. Alternatively, you can use array methods like
forEach(), map(), filter(), and reduce() to perform operations on
each value in the array.

Q: What are some common mistakes when working with


arrays?
A: One common mistake is accessing an index that doesn't
exist in the array, which can result in an error. Another mistake
is forgetting to use bracket notation to access values in the
array. Additionally, forgetting to use the var keyword when
declaring a new variable can result in unexpected behavior
when working with arrays.

Page 91
Section 6: Objects in JavaScript
Welcome to Section 6 of our JavaScript Development
Workbook! In this section, we will be diving into one of the
most important and complex topics in JavaScript: Objects. Just
like in real life, objects in programming are essential tools that
allow us to organize and manage information in a logical way.
And, just like in real life, they can be a bit tricky to wrap your
head around at first.

We'll start by discussing the difference between built-in


JavaScript objects and custom objects, so you can understand
how objects are already being used in JavaScript. Then, we'll
explore the different ways to create objects, including object
literals and constructors. From there, we'll delve into properties
and methods, two of the most important aspects of objects.
Finally, we'll talk about prototypes and inheritance, which can
be a bit more advanced, but will give you a powerful tool for
creating complex and flexible code. So, grab your thinking caps
and let's dive into the fascinating world of objects in JavaScript!

Built-in JavaScript Objects Versus Custom


Objects
In JavaScript, there are two types of objects: built-in objects
and custom objects. In this section, we will discuss the
differences between the two and how to create custom
objects.

Built-In Objects
JavaScript has several built-in objects that are available by
default. These objects include:

Math: provides mathematical functions and constants


Date: provides methods for working with dates and times

Page 92
String: provides methods for working with strings
Array: provides methods for working with arrays
Object: the base object for all JavaScript objects
These built-in objects can be accessed and used directly in
your code.

Custom Objects
In addition to the built-in objects, you can also create your own
custom objects in JavaScript. Custom objects can have their
own properties and methods, just like built-in objects.

To create a custom object, you can use either object literals or


object constructors. Object literals are a quick and easy way to
create an object, while object constructors provide more
flexibility and allow you to create multiple instances of an
object.

Properties and Methods


Objects in JavaScript have properties and methods. Properties
are variables that hold values, while methods are functions that
perform actions.

To access a property or method of an object, you use dot


notation. For example, to access the length property of a string
object, you would use the following syntax: string.length.

Prototypes and Inheritance


JavaScript supports prototypal inheritance, which allows you to
create new objects based on existing objects. The existing
object serves as a prototype for the new object, and any
properties or methods defined in the prototype are inherited
by the new object.

Page 93
Prototypal inheritance allows you to create more efficient and
organized code by reusing existing code instead of creating
new objects from scratch.

In summary, JavaScript has built-in objects that provide


functionality for common tasks, and you can also create your
own custom objects with properties and methods. Prototypal
inheritance allows you to reuse existing code and create new
objects based on existing objects.

Objects, Instances, Properties and: A


Metaphor
Let's use an analogy to explain objects and instances in
JavaScript. Think of a set of architectural plans for a building.
The plans would define the overall structure and design of the
building, including its various rooms, doors, and windows. In
JavaScript, we can think of these plans as the blueprint or
prototype for an object.

Now imagine that we use those architectural plans to build an


actual building. This building is a concrete instance of the
plans, with specific values for each of its features. For example,
the blueprint may specify that a building has a red front door,
three bedrooms, and two bathrooms. The actual building
constructed based on these plans would be an instance of that
blueprint, with those specific values for each of its features.

In JavaScript, we can create instances of an object by using its


constructor function. The constructor function defines the
blueprint for the object, and each time we call it, we create a
new instance of that object with specific values for its
properties.

Page 94
In our architectural analogy, we can think of the constructor
function as the construction crew that builds the building
based on the architectural plans. Each time the crew builds a
new building, it uses the same set of plans, but the resulting
building is unique, with its own specific values for its features.

When we create an object instance in JavaScript, we can


assign it properties, which are like adjectives that describe the
object. For example, we could give a building instance a "color"
property that describes its exterior color. Similarly, we can give
a JavaScript object instance properties that describe its
characteristics.

Finally, we can also give our JavaScript object instance


methods, which are like verbs that describe the actions that
the object can perform. In our architectural analogy, a building
might have methods like "openDoor" or "turnOnLights".
Similarly, a JavaScript object can have methods that perform
actions or computations based on the object's properties.

Creating Objects: Object literals and


constructors
In JavaScript, objects can be created in two main ways: using
object literals and constructors. Let's explore each method.

Object Literals
Object literals are a simple and concise way to create objects in
JavaScript. An object literal is defined using curly braces {} and
consists of key-value pairs separated by commas. The keys in
an object literal are strings, and the values can be of any data
type, including other objects.

Here's an example of creating an object literal:

Page 95
const person = {
name: 'John',
age: 30,
address: {
street: '123 Main St',
city: 'Anytown',
state: 'CA'
}
};

In this example, person is an object with three properties:


name, age, and address. The address property is itself an object
with three properties.

Constructors
Constructors are functions that create new objects. To create a
new object using a constructor, you use the new keyword
followed by the name of the constructor function. Constructors
are named with a capitalized first letter to distinguish them
from regular functions.

Here's an example of creating an object using a constructor:

function Person(name, age, address) {


this.name = name;
this.age = age;
this.address = address;
}

const person = new Person('John', 30, { street: '123


Main St', city: 'Anytown', state: 'CA' });

In this example, Person is a constructor function that takes


three parameters: name, age, and address. The this keyword

Page 96
refers to the new object being created, and the properties of
the object are set to the values passed in as arguments.

Comparing Object Literals and Constructors


Object literals and constructors are both valid ways to create
objects in JavaScript, but they have some differences.

Object literals are simpler and easier to read, especially for


small objects with a few properties. Constructors are better
suited for creating complex objects with many properties and
methods.

Constructors also allow for the use of prototypes and


inheritance, which we'll cover in later sections.

Overall, both object literals and constructors are useful tools for
creating objects in JavaScript, and the choice between them
depends on the specific needs of your program.

Properties and methods


In JavaScript, an object is like a little world of its own, complete
with properties and methods. In this section, we'll dive deeper
into these concepts and learn how to use them effectively.

Accessing Properties
Properties are like adjectives that describe an object. They can
be accessed and modified using dot notation or bracket
notation. For example, let's say we have an object called person
with properties name, age, and occupation:

let person = {
name: "John Doe",
age: 35,
occupation: "Web Developer"

Page 97
};

We can access the properties of this object using dot notation


or bracket notation:

console.log(person.name); // "John Doe"


console.log(person["age"]); // 35

Modifying Properties
Properties can be modified using the same syntax as accessing
them. For example, we can change the occupation property of
our person object like this:

person.occupation = "Software Engineer";


console.log(person.occupation); // "Software Engineer"

Adding Properties
New properties can be added to an object using dot
notation or bracket notation. For example, let's add a
location property to our person object:

person.location = "San Francisco";


console.log(person.location); // "San Francisco"

Methods
Methods are like verbs that describe what an object can do.
They are functions that are associated with an object and can
be called to perform a specific action. For example, let's add a
greet method to our person object:

let person = {
name: "John Doe",
age: 35,

Page 98
occupation: "Web Developer",
greet: function() {
console.log("Hello, my name is " + this.name +
".");
}
};

person.greet(); // "Hello, my name is John Doe."

The this keyword refers to the current object, so this.name


refers to the name property of the person object.

In summary, properties and methods are essential concepts in


JavaScript objects. Properties are like adjectives that describe
an object, while methods are like verbs that describe what an
object can do. By accessing and modifying properties, and
calling methods, you can create powerful and dynamic objects
in your JavaScript programs.

Prototypes and inheritance


Prototypes and inheritance are some of the most powerful
features of JavaScript, allowing you to create complex and
dynamic objects. In this section, we’ll explore these concepts in
depth.

Introduction to Prototypes
In JavaScript, every object has a prototype, which is a reference
to another object. The prototype object acts as a template for
the object and contains the object's properties and methods.
When a property or method is called on an object, JavaScript
first looks for that property or method on the object itself. If it's
not found, it looks for it on the prototype object. If it's still not
found, it looks for it on the prototype's prototype, and so on,
until it reaches the root prototype object. This is called the
prototype chain.

Page 99
Creating a Prototype Object
You can create a prototype object using the Object()
constructor or by using an object literal. For example:

// Using the Object() constructor


var myPrototype = new Object();
myPrototype.myProperty = "Hello, World!";
myPrototype.myMethod = function() {
console.log(this.myProperty);
};

// Using an object literal


var myLiteralPrototype = {
myProperty: "Hello, World!",
myMethod: function() {
console.log(this.myProperty);
}
};

Creating an Object with a Prototype


To create an object with a specific prototype, you can use the
Object.create() method. For example:

var myObject = Object.create(myPrototype);

In this example, myObject is created with myPrototype as its


prototype.

Inheritance and the Prototype Chain


Inheritance in JavaScript is implemented through the
prototype chain. When you call a method on an object,
JavaScript will look for that method on the object itself and
then on its prototype object. If the method is not found on the
prototype object, JavaScript will look for it on the prototype's

Page 100
prototype object, and so on, until it reaches the root prototype
object.

Overriding Properties and Methods


If you want to override a property or method on an object's
prototype, you can do so by simply assigning a new value to
that property or method on the object itself. For example:

myObject.myProperty = "Goodbye, World!";

Now, when you call myObject.myMethod(), it will output


"Goodbye, World!" instead of "Hello, World!".

Prototypes and inheritance are powerful features of JavaScript


that allow you to create complex and dynamic objects. By
understanding how prototypes work, you can create more
efficient and maintainable code.

Classes and Objects in the Real World:


Vehicles
In this section, we'll apply our knowledge of objects and
prototypes to a real-world example of vehicles. We'll create a
Vehicle class and demonstrate how child classes like
Ambulance and Bus can inherit properties and methods from
the parent.

Creating the Vehicle Class


Let's start by creating the Vehicle class. We'll give it a
constructor method that takes in parameters for the make,
model, and year of the vehicle:

class Vehicle {
constructor(make, model, year) {

Page 101
this.make = make;
this.model = model;
this.year = year;
}

getInfo() {
return `Make: ${this.make}, Model: ${this.model},
Year: ${this.year}`;
}
}

In this example, we've defined a Vehicle class with a


constructor method that takes in make, model, and year
parameters. We've also defined an instance method called
getInfo() that returns a string with the make, model, and year
of the vehicle.

Inheriting Properties and Methods


Now that we've created our Vehicle class, let's create child
classes that inherit properties and methods from the parent.
For example, an Ambulance class could inherit the make,
model, and year properties from the Vehicle class, but also
have its own unique properties and methods.

class Ambulance extends Vehicle {


constructor(make, model, year, hasSiren) {
super(make, model, year);
this.hasSiren = hasSiren;
}

getInfo() {
return `${super.getInfo()}, Has Siren:
${this.hasSiren}`;
}

Page 102
useSiren() {
console.log('WEE-OOH WEE-OOH');
}
}

In this example, we've defined an Ambulance class that


extends the Vehicle class. The Ambulance class has its own
hasSiren property, and overrides the getInfo() method to
include this property in the returned string. We've also defined
a unique method for the Ambulance class called useSiren()
that logs a siren sound to the console.

Similarly, we can create a Bus class that extends the Vehicle


class and has its own unique properties and methods:

class Bus extends Vehicle {


constructor(make, model, year, numSeats) {
super(make, model, year);
this.numSeats = numSeats;
}

getInfo() {
return `${super.getInfo()}, Number of Seats:
${this.numSeats}`;
}

driveToWork() {
console.log(`Starting the engine of the
${this.make} ${this.model} and driving to work with
${this.numSeats} seats!`);
}
}

In this example, we've defined a Bus class that extends the


Vehicle class. The Bus class has its own numSeats property, and
overrides the getInfo() method to include this property in the

Page 103
returned string. We've also defined a unique method for the
Bus class called driveToWork() that logs a message to the
console indicating the vehicle is being driven to work.

Using the Classes


Now that we have our classes defined, let's see how we can use
them to create actual vehicles.

Creating an Ambulance
Let's start by creating an instance of the Ambulance class. We
can do this by calling the constructor function and passing in
the required parameters:

const ambulance = new Ambulance('Ford', 'Ambulance', '2015',


120, 4, true, 'siren');

Here, we're creating a new Ambulance object with a make of


"Ford", a model of "Ambulance", a year of 2015, a top speed of
120 mph, 4 wheels, a first-aid kit, a siren, and the ability to
transport patients.

Creating a Bus
Next, let's create an instance of the Bus class. We can do this in
a similar way to creating an Ambulance:

const bus = new Bus('Volvo', 'Bus', '2020', 80, 6, 50,


2);

Here, we're creating a new Bus object with a make of "Volvo", a


model of "Bus", a year of 2020, a top speed of 80 mph, 6 wheels,
a capacity of 50 passengers, and 2 floors.

Page 104
Using the Methods
Now that we have our objects created, we can start using the
methods we defined in our classes.

Let's say we want to know the maximum distance the


ambulance can travel on a full tank of gas. We can call the
maxDistance method on the ambulance object like this:

console.log(ambulance.maxDistance());
// Output: The maximum distance this ambulance can
travel on a full tank of gas is 480 miles.

Similarly, we can call the boardPassenger method on the bus


object to add a passenger to the bus:

bus.boardPassenger();
console.log(bus.passengers);
// Output: 1

We can also call the blowHorn method on the ambulance


object to sound the siren:

ambulance.blowHorn();
// Output: WEEEE-OOOO-WEEEE-OOOO

Inheritance in Action
Remember that because the Ambulance and Bus classes
inherit from the Vehicle class, they have access to all of the
properties and methods defined in that class as well. For
example, we can call the start method on both the ambulance
and bus objects to start the engines:

ambulance.start();

Page 105
// Output: The Ford Ambulance from 2015 is starting up.

bus.start();
// Output: The Volvo Bus from 2020 is starting up.

By using classes and inheritance, we can easily create and


manage objects that share common properties and methods.
We can also customize those objects by adding additional
properties and methods specific to each class.

Code Exercises
Code Exercise 6.1: Creating a Class
In this exercise, you will create a class in JavaScript and perform
an interesting operation on it.

1. Create a new class called Animal.


2. The class should have at least two properties, name and
sound.
3. The class should have a method called makeSound()
that logs the sound of the animal to the console.
4. Create at least two instances of the Animal class with
unique names and sounds.
5. Call the makeSound() method on each of the instances
and observe the output in the console.

Code Exercise 6.2: Creating Subclasses


In this exercise, you will create a class and two subclasses of
that class in JavaScript and perform an interesting operation
on them.

1. Create a new class called Vehicle.


2. The class should have at least two properties, make and
model.
3. The class should have a method called honk() that logs
a generic honking sound to the console.

Page 106
4. Create two subclasses of the Vehicle class called Car
and Truck.
5. The Car subclass should have a method called drive()
that logs a message to the console indicating that the
car is driving.
6. The Truck subclass should have a method called haul()
that logs a message to the console indicating that the
truck is hauling something.
7. Create at least one instance of each subclass with
unique makes and models.
8. Call the honk() method on each instance of the Vehicle
class and observe the output in the console.
9. Call the drive() method on the Car instance and observe
the output in the console.
10. Call the haul() method on the Truck instance and
observe the output in the console.

Critical Points
Built-in JavaScript Objects Versus Custom Objects:
● Built-in objects are pre-defined objects in JavaScript,
like Array, Date, and Math.
● Custom objects are objects that you define and create
yourself.
● Both types of objects can have properties and methods.

Creating Objects: Object Literals and Constructors:


● Object literals are a way to create a new object with
properties and methods.
● Constructors are functions used to create new objects
based on a template.
● The 'this' keyword is used to refer to the object that the
constructor is creating.

Properties and Methods:


● Properties are the characteristics or attributes of an
object.

Page 107
● Methods are the actions or behaviors that an object can
perform.
● Properties and methods are accessed using dot
notation or bracket notation.

Prototypes and Inheritance:


● The prototype is an object that is shared among all
instances of a class.
● Inheritance is the process by which a subclass inherits
properties and methods from its parent class.
● The prototype chain is the mechanism by which
JavaScript searches for properties and methods on an
object.

The FAQ
Q: What is an object in JavaScript?
A: An object is a collection of properties and methods,
represented as key-value pairs, that can be used to store and
manipulate data in JavaScript.

Q: How do I create an object in JavaScript?


A: There are two ways to create an object in JavaScript: using
object literals or using constructors.

Q: What is a constructor in JavaScript?


A: A constructor is a function that is used to create objects. It
can be used to define the properties and methods of an object
and to set their initial values.

Q: What is inheritance in JavaScript?


A: Inheritance is a way to create a new object by copying
properties and methods from an existing object. It allows you
to create new objects that are similar to existing objects, but
with some differences.

Page 108
Q: How do I inherit properties and methods in JavaScript?
A: In JavaScript, you can use prototypes to inherit properties
and methods from existing objects. You can create a new
object that is linked to an existing object, and then add or
override properties and methods as needed.

Q: What is the difference between built-in JavaScript objects


and custom objects?
A: Built-in JavaScript objects are objects that are part of the
JavaScript language, such as String, Number, and Array.
Custom objects are objects that are created by the
programmer, using constructors or object literals.

Q: What are properties and methods in JavaScript objects?


A: Properties are values that are stored in an object,
represented as key-value pairs. Methods are functions that are
stored in an object, and can be used to perform operations on
the object's properties.

Q: How do I access properties and methods in JavaScript


objects?
A: You can access properties and methods in JavaScript objects
using dot notation or bracket notation. Dot notation is used to
access properties and methods directly, while bracket notation
is used to access them indirectly using a string or a variable.

Q: What is the difference between an instance and a class in


JavaScript?
A: A class is a blueprint for creating objects, while an instance is
a specific object that is created from a class. When you create a
new object from a class, it is called an instance of that class.

Page 109
Section 7: Error Handling
As much as we strive to write perfect code, it's inevitable that
errors will arise at some point. Whether it's a syntax error,
runtime error, or a logic error, knowing how to effectively
handle errors is crucial to ensuring our programs run smoothly.

In this section, we'll cover the different types of errors you may
encounter in JavaScript, including syntax, runtime, and logic
errors. We'll also explore how you can use developer tools in
your browser to help identify and debug errors in your code.

Additionally, we'll look at how try/catch/finally statements can


be used to handle errors in a structured and organized
manner, and how throwing and catching exceptions can
provide even more control over error handling. So, let's dive in
and learn how to tackle those pesky errors in our code!

Types of errors (syntax, runtime, logic)


In JavaScript, errors can occur for a variety of reasons.
Understanding the different types of errors can help you
diagnose and fix issues in your code more efficiently. The three
main types of errors in JavaScript are: syntax errors, runtime
errors, and logic errors.

Syntax Errors
Syntax errors occur when you have incorrect syntax in your
code. For example, if you forget to close a parenthesis or add
an extra semicolon, you will get a syntax error. These errors are
detected by the JavaScript interpreter during the compilation
phase, before the code is executed. Here's an example of a
syntax error:

function addNumbers(a, b) {

Page 110
return a + b;
// syntax error: missing closing curly brace

Runtime Errors
Runtime errors occur during the execution of your code. These
errors happen when JavaScript is unable to complete an
operation due to unexpected input, such as trying to divide by
zero or accessing a variable that does not exist. Runtime errors
can cause your code to crash, so it's important to handle them
properly. Here's an example of a runtime error:

function divide(a, b) {
return a / b;
}

console.log(divide(10, 0)); // runtime error: divide by


zero

Logic Errors
Logic errors are the most subtle type of error and can be the
most difficult to track down. These errors occur when your
code executes without errors, but does not produce the
expected result. Logic errors are caused by flaws in the design
or implementation of your code. Here's an example of a logic
error:

function calculateArea(radius) {
return 3.14 * radius * radius;
}

console.log(calculateArea(4)); // returns 50.24, but


should return 50.24

Page 111
It's important to know the different types of errors so that you
can properly diagnose and fix issues in your code. In the next
sections, we'll explore how to handle errors using
try/catch/finally statements and throwing and catching
exceptions.

Using Developer Tools in Your Browser


When writing JavaScript code, you may encounter errors that
prevent your code from running as expected. Fortunately,
modern browsers come equipped with developer tools that
can help you identify and fix these errors.

Reviewing the Console


The console is a powerful tool that allows you to log messages,
errors, and other information from your code. You can open the
console by pressing F12 on your keyboard or right-clicking on a
webpage and selecting "Inspect" or "Inspect Element."

To log messages to the console, you can use the console.log()


method. For example:

console.log("Hello, world!");

This will log the message "Hello, world!" to the console.

Tracing Variables
Another useful feature of the developer tools is the ability to
trace variables. This allows you to see the value of a variable at
any point in your code. To do this, you can use the console.log()
method to log the value of the variable to the console.

For example:

Page 112
let x = 5;
console.log(x);

This will log the value of x (which is 5) to the console.

Inserting Breakpoints
Sometimes, you may need to pause your code at a specific
point in order to debug it. To do this, you can insert a
breakpoint in your code using the developer tools.

To insert a breakpoint, simply click on the line number in the


code editor where you want to pause the code. When you run
your code, it will pause at this point and you can use the
developer tools to inspect the code and fix any errors.

By using the developer tools in your browser, you can quickly


and easily identify and fix errors in your JavaScript code.

Code Exercise
Code Exercise 7.1: Inserting Breakpoints
In this lab, you will practice inserting breakpoints in JavaScript
code using developer tools to locate and fix an error.

1) Create an HTML file with a script tag that includes a


JavaScript file with an error in it. For example:

<html>
<head>
<script src="script.js"></script>
</head>
<body>
<h1>Inserting Breakpoints Lab</h1>

Page 113
</body>
</html>

2) Create a JavaScript file with the following code, which


contains an error:

function calculateSum(arr) {
var sum = 0;
for (var i = 0; i <= arr.length; i++) {
sum += arr[i];
}
return sum;
}

var numbers = [1, 2, 3, 4, 5];


var total = calculateSum(numbers);
console.log('The total is: ' + total);

The error in this code is that the for loop in the calculateSum
function is iterating one too many times, resulting in an
undefined value being added to the sum.

3) Open the HTML file in your browser and open the developer
tools (typically accessed by right-clicking on the page and
selecting "Inspect" or pressing F12 on Windows or
Option-Command-I on Mac).

4) Navigate to the "Sources" or "Debugger" tab in the developer


tools and find your JavaScript file.

Page 114
5) Find the line with the error (in this case, line 3 of the
calculateSum function) and click on the line number to insert a
breakpoint.

6) Refresh the page in your browser to run the code with the
breakpoint.

7) The code will pause execution at the breakpoint, and you


can now use the debugger tools to examine the value of
variables and step through the code line by line to identify and
fix the error. In this case, you can see that the loop is iterating
one too many times by examining the value of i and arr[i] in
each iteration.

8) Once you have identified and fixed the error, remove the
breakpoint and refresh the page to run the code again without
pausing at the breakpoint.

Page 115
9) Check the console output to ensure that the error has been
resolved and the code is running correctly.

try/catch/finally statements
In JavaScript, the try/catch/finally statements provide a way to
handle errors that may occur in your code.

The try Block


The try block is used to enclose a section of code that may
throw an error. Within this block, any errors that are thrown will
be caught by the subsequent catch block.

try {
// Code that may throw an error
} catch (error) {
// Code to handle the error
}

The catch Block


The catch block is used to handle any errors that are thrown
within the preceding try block. The catch block must have a
parameter that represents the error object, which contains
information about the error that was thrown.

try {
// Code that may throw an error
} catch (error) {
// Code to handle the error
}

Page 116
The finally Block
The finally block is optional and is used to specify a block of
code that will always be executed, regardless of whether an
error was thrown or not. This block is often used for cleanup
code, such as closing a database connection or releasing
resources.

try {
// Code that may throw an error
} catch (error) {
// Code to handle the error
} finally {
// Code that will always be executed
}

Putting it All Together


Let's see an example of how to use try/catch/finally statements
to handle errors in a function that divides two numbers.

function divide(a, b) {
try {
if (b === 0) {
throw new Error("Cannot divide by zero!");
}
return a / b;
} catch (error) {
console.error(error);
return null;
} finally {
console.log("Division operation complete.");
}
}

console.log(divide(10, 5)); // Output: 2


console.log(divide(10, 0)); // Output: null

Page 117
In this example, the try block contains the code that may throw
an error, which is the division of two numbers. If the second
number is zero, the throw statement will create a new Error
object with a message indicating that the division is not
possible. The catch block contains code to handle this error,
which logs the error message to the console and returns null.
The finally block contains code to always be executed, which
logs a message indicating that the division operation is
complete.

By using try/catch/finally statements, we can handle errors that


may occur in our code and ensure that our program continues
to run smoothly.

Code Exercise
Code Exercise 7.2: Try/Catch/Finally
In this lab, you will practice using the try/catch/finally
statements to handle errors in your JavaScript code.

1) Write a function called divide that takes two parameters,


numerator and denominator, and returns their division result.
However, if the denominator is 0, the function should throw an
error with the message "Division by zero".

2) In your main program, call the divide function with different


values for the numerator and denominator parameters,
including 0 for the denominator.

3) Surround each function call with a try/catch/finally


statement that catches the error thrown by the divide function
and logs it to the console. The finally block should log a
message indicating that the function call has finished.

Page 118
4) Test your program by intentionally causing errors and
verifying that they are handled correctly by the try/catch/finally
blocks.

5) Once you have verified that your code works correctly, try to
modify the divide function to throw a different type of error
and observe the behavior of the try/catch/finally blocks.

Throwing and catching exceptions


JavaScript allows you to create your own custom exceptions by
using the throw statement. You can then use the try and catch
statements to handle these exceptions.

The throw statement


The throw statement allows you to create a new exception and
specify a value to be thrown. This value can be of any type,
including strings, numbers, and objects.

Here's an example:
function divideByZero(num1, num2) {
if (num2 === 0) {
throw "Cannot divide by zero!";
} else {
return num1 / num2;
}
}

try {
console.log(divideByZero(10, 0));
} catch (error) {
console.log("Error: " + error);
}

Page 119
In this example, the divideByZero function checks if the second
parameter is 0, and if it is, it throws an exception with the
message "Cannot divide by zero!". In the try block, we call the
divideByZero function with arguments 10 and 0. Since the
second argument is 0, an exception is thrown. This exception is
caught in the catch block, where we log the error message to
the console.

The try and catch statements


The try and catch statements allow you to handle exceptions
thrown in your code. The try statement contains the code that
may throw an exception, while the catch statement contains
the code that will handle the exception if it's thrown.

Here's an example:
try {
let myVar = someFunctionThatMightThrowAnError();
console.log(myVar);
} catch (error) {
console.log("An error occurred: " + error);
}

In this example, the someFunctionThatMightThrowAnError


function may throw an error. We wrap the call to this function
in a try block, and if an error is thrown, it will be caught in the
catch block, where we log the error message to the console.

The finally statement


The finally statement allows you to execute code after the try
and catch blocks, regardless of whether an exception was
thrown or not.

Here's an example:
try {
console.log("Executing try block");

Page 120
throw "An error occurred";
} catch (error) {
console.log("An error occurred: " + error);
} finally {
console.log("Executing finally block");
}

In this example, the try block throws an exception, which is


caught in the catch block. The finally block is then executed,
logging the message "Executing finally block" to the console.

Code Exercise
Code Exercise 7.3: Throwing Exceptions

1) Create a new HTML file with an empty <body> element and a


<script> tag. Add the following code inside the <script> tag:
try {
// code that may throw an exception
throw new Error('Something went wrong');
} catch (error) {
// code to handle the exception
console.error(error);
}

2) Save the file and open it in your web browser.

3) Open the developer tools by pressing F12 or Ctrl+Shift+I


(Windows/Linux) or Cmd+Opt+I (macOS).

4) Reload the page to see the exception thrown and caught by


the try/catch block.

Page 121
5) In the console tab of the developer tools, you should see an
error message with the stack trace and the message
"Something went wrong".

6) Experiment with changing the code inside the try block to


throw different types of exceptions, such as a TypeError, a
RangeError, or a custom exception.

7) Use the throw statement to manually throw an exception,


and catch it using a try/catch block.

Critical Points
Types of Errors:
● Syntax errors occur when code does not follow the
correct syntax of the programming language
● Runtime errors happen when code runs but encounters
an unexpected behavior
● Logic errors occur when code produces an unexpected
result, but no error is thrown

Using Developer Tools in Your Browser:


● Developer tools are built-in tools in browsers that allow
developers to inspect, debug, and optimize their code
● The console is a useful tool for debugging JavaScript
errors and for printing messages to help with
development
● Tracing variables and inserting breakpoints can help
with tracking down the source of errors

try/catch/finally Statements:
● try/catch/finally statements provide a way to handle
errors that may occur in JavaScript code
● The try block contains the code to be executed, and the
catch block contains the code to be executed if an error
occurs

Page 122
● The finally block contains the code that will be executed
regardless of whether an error occurs or not

Throwing and Catching Exceptions:


● Exceptions can be thrown in JavaScript code using the
throw keyword
● The catch block can be used to handle the thrown
exception and provide a response
● Custom exceptions can be created to provide more
specific information about errors

The FAQ
Q: What are the most common types of errors in JavaScript?
A: The most common types of errors in JavaScript are syntax
errors, runtime errors, and logical errors. Syntax errors occur
when the code is not written according to the proper syntax
rules. Runtime errors occur when the code is executing and
encounters an unexpected condition. Logical errors occur
when the code executes but produces unexpected results.

Q: How can I use the developer tools in my browser to find


errors in my JavaScript code?
A: The developer tools in your browser provide a variety of tools
for debugging JavaScript, including a console for logging
messages, the ability to trace variables, and the option to insert
breakpoints to pause code execution at specific points. These
tools allow you to identify and isolate errors in your code more
easily.

Q: What are try/catch/finally statements and how do I use


them?
A: Try/catch/finally statements are a way to handle errors in
JavaScript code. The try block contains the code that may
throw an error, and the catch block contains the code to
execute if an error occurs. The finally block contains code that

Page 123
will execute whether or not an error occurs. These statements
allow you to gracefully handle errors in your code and prevent
the code from crashing.

Q: How do I throw and catch exceptions in JavaScript?


A: To throw an exception, you can use the throw keyword
followed by an error message. To catch an exception, you can
use a try/catch statement. In the try block, you can execute
code that may throw an exception. In the catch block, you can
catch the exception and handle it accordingly, such as logging
an error message or displaying an error to the user.

Page 124
Section 8: DOM Manipulation

As a web developer, understanding how the Document Object


Model (DOM) works is crucial for building dynamic and
interactive web pages. The DOM represents the structure of a
web page as a hierarchical tree-like structure of objects that
can be manipulated with JavaScript. Every element on a web
page, including HTML tags, text, and images, is represented as
a node in the DOM tree, and each node has properties and
methods that can be accessed and modified using JavaScript.

DOM manipulation is essential for creating dynamic and


interactive web pages that respond to user actions. By
accessing and modifying the DOM elements, JavaScript can
change the appearance, content, and behavior of a web page
in real-time. With the ability to modify DOM elements, you can
create engaging user interfaces, animations, and other
interactive features that improve the user experience on your
web page.

In this section, we'll cover the basics of the DOM, including how
to access and modify DOM elements using JavaScript, how to
change the styling of elements with CSS, and how to respond
to user events. By the end of this section, you'll have a solid
understanding of the DOM and how to use it to create
dynamic and interactive web pages with JavaScript. So let's
dive in and start exploring the amazing world of DOM
manipulation!

The Document Object Model (DOM)


When a web page is loaded, the browser creates a model of
the page called the Document Object Model (DOM). The DOM
is essentially an object-oriented representation of the HTML
elements on the page. By manipulating the DOM using

Page 125
JavaScript, we can add interactivity and dynamic behavior to a
web page.

DOM Tree Structure


The DOM is structured like a tree, with each HTML element
represented as a node in the tree. The top node of the tree is
called the Document Object, and it represents the entire HTML
document. Each child node represents an HTML element, such
as a paragraph or an image. This hierarchical structure allows
us to easily access and modify specific elements on a web page
using JavaScript.

Accessing DOM elements


To modify an element in the DOM, you first need to access it.
There are several ways to access DOM elements in JavaScript,
including:

getElementById()
The getElementById() method is used to select a single
element by its unique ID. To use this method, simply pass the
ID of the element you want to select as a string:

const myElement = document.querySelector(".my-class");

querySelector()
The querySelector() method is used to select a single element
based on a CSS selector. This method returns the first element
that matches the selector:

const myElement = document.querySelector(".my-class");

Page 126
querySelectorAll()
The querySelectorAll() method is used to select all elements
that match a CSS selector. This method returns a NodeList
object, which is similar to an array:

const myElements =
document.querySelectorAll(".my-class");

Elements by Tag Name or Class Name


You can also access elements by their tag name or class name
using the getElementsByTagName() and
getElementsByClassName() methods:

const myElements = document.getElementsByTagName("p");


const myElements =
document.getElementsByClassName("my-class");

In addition to these methods, there are other ways to access


elements in the DOM, such as using the parentNode,
nextSibling, and previousSibling properties to traverse the
DOM tree. The choice of method depends on the specific
requirements of your project.

Remember that accessing DOM elements can be slow,


especially when using complex selectors or large collections of
elements. It's important to use the most efficient method
possible and to cache references to frequently used elements
to improve performance.

Dom Manipulation: In Action


Here's an example HTML file that changes the text of a
paragraph using JavaScript and the getElementById() method:

Page 127
<!DOCTYPE html>
<html>
<head>
<title>Change Paragraph Text</title>
<style>
/* Add some basic styles to the paragraph */
p {
font-size: 24px;
color: navy;
font-weight: bold;
text-align: center;
}
</style>
</head>
<body>
<p id="my-paragraph">This is the original
text.</p>

<!-- Add a button that will change the paragraph text


-->
<button onclick="changeText()">Change
Text</button>

<script>
// Define a function that will change the text of the
paragraph
function changeText() {
// Use the getElementById() method to select the
paragraph element
var myParagraph =
document.getElementById("my-paragraph");

// Change the text of the paragraph


myParagraph.textContent = "This is the new
text!";
}
</script>

Page 128
</body>
</html>

In this example, we first define a paragraph element with an id


of "my-paragraph". We also add a button element that has an
onclick attribute set to a JavaScript function called
changeText().

In the JavaScript section, we define the changeText() function,


which uses the getElementById() method to select the
paragraph element with the id of "my-paragraph". We then
change the text content of the paragraph using the
textContent property.

When the button is clicked, the changeText() function is called


and the text of the paragraph is changed to "This is the new
text!".

Modifying DOM Elements


Once you have accessed an element in the DOM, you can then
modify it in various ways. In this section, we’ll explore some of
the ways you can modify DOM elements using JavaScript.

Modifying Text Content


One of the most common modifications to a DOM element is
to change the text content. You can do this using the
textContent property. Let’s take a look at an example:

<!DOCTYPE html>
<html>
<body>
<p id="my-paragraph">Hello, world!</p>
<button onclick="changeText()">Change Text</button>

Page 129
<script>
function changeText() {
var paragraph =
document.getElementById("my-paragraph");
paragraph.textContent = "Goodbye, world!";
}
</script>
</body>
</html>

In this example, we have a paragraph element with the ID


my-paragraph. We also have a button that, when clicked, calls
the changeText() function. The changeText() function first gets
a reference to the paragraph element using getElementById(),
and then sets the textContent property of the paragraph to
"Goodbye, world!".

Modifying HTML Content


You can also modify the HTML content of an element using the
innerHTML property. This property allows you to set or get the
HTML content of an element. Let’s look at an example:

<!DOCTYPE html>
<html>
<body>
<div id="my-div">
<p>Hello, world!</p>
</div>
<button onclick="changeHTML()">Change HTML</button>

<script>
function changeHTML() {
var div = document.getElementById("my-div");
div.innerHTML = "<p>Goodbye, world!</p>";
}

Page 130
</script>
</body>
</html>

In this example, we have a div element with the ID my-div.


Inside the div, we have a paragraph element with the text
"Hello, world!". We also have a button that, when clicked, calls
the changeHTML() function. The changeHTML() function first
gets a reference to the div element using getElementById(),
and then sets the innerHTML property of the div to the new
HTML content, in this case, a new paragraph element with the
text "Goodbye, world!".

Modifying Attributes
You can also modify the attributes of an element using
JavaScript. You can use the getAttribute() method to get the
value of an attribute, and the setAttribute() method to set the
value of an attribute. Let’s look at an example:

<!DOCTYPE html>
<html>
<body>
<img id="my-image" src="cat.jpg" alt="A cute cat">
<button onclick="changeImage()">Change
Image</button>

<script>
function changeImage() {
var image =
document.getElementById("my-image");
image.setAttribute("src", "dog.jpg");
image.setAttribute("alt", "A cute dog");
}
</script>
</body>

Page 131
</html>

In this example, we have an image element with the ID


my-image. It has a src attribute with the value "cat.jpg", and an
alt attribute with the value "A cute cat". We also have a button
that, when clicked, calls the changeImage() function. The
changeImage() function first gets a reference to the image
element using getElementById(), and then uses setAttribute()
to set the src attribute to "dog.jpg" and the alt attribute to "A
cute dog".

Modifying CSS
CSS is used to style HTML elements and make them look
beautiful. JavaScript can be used to dynamically modify the
CSS styles applied to elements in the DOM.

Modifying inline styles


One way to modify CSS is to change an element's inline style.
The inline style is the style attribute of an HTML element that
can be used to apply a style to that element. JavaScript can be
used to modify the value of the style attribute and thus modify
the style of the element.

Here's an example that modifies the font color of a paragraph


element using the style attribute:

<!DOCTYPE html>
<html>
<head>
<style>
p {
color: red;
}

Page 132
</style>
</head>
<body>
<p id="myParagraph">This is a paragraph.</p>
<button onclick="changeColor()">Change
color</button>
<script>
function changeColor() {
var p = document.getElementById("myParagraph");
p.style.color = "blue";
}
</script>
</body>
</html>

In this example, a paragraph element is created with an id of


"myParagraph". The JavaScript function "changeColor" is called
when the button is clicked, and it modifies the color style of the
paragraph element to blue.

Modifying classes
Another way to modify CSS is to add or remove classes from
elements in the DOM. A class is a collection of CSS properties
that can be applied to multiple elements. By adding or
removing classes from elements, you can apply or remove
specific styles to those elements.

Here's an example that adds and removes a class from a


paragraph element when a button is clicked:

<!DOCTYPE html>
<html>
<head>
<style>
.blue {

Page 133
color: blue;
}
.underline {
text-decoration: underline;
}
</style>
</head>
<body>
<p id="myParagraph">This is a paragraph.</p>
<button onclick="addStyles()">Add styles</button>
<button onclick="removeStyles()">Remove
styles</button>
<script>
function addStyles() {
var p = document.getElementById("myParagraph");
p.classList.add("blue");
p.classList.add("underline");
}

function removeStyles() {
var p = document.getElementById("myParagraph");
p.classList.remove("blue");
p.classList.remove("underline");
}
</script>
</body>
</html>

In this example, two classes are defined in the CSS: "blue" and
"underline". When the "Add styles" button is clicked, both
classes are added to the paragraph element, applying the
styles defined in those classes. When the "Remove styles"
button is clicked, both classes are removed from the paragraph
element, removing the styles defined in those classes.

Page 134
Responding to events
The web is an interactive space, and users expect that their
actions will have consequences. That's where event handling
comes into play. In this section, we'll explore how to listen for
events and respond to them using JavaScript.

Event Listeners
In JavaScript, we can add an event listener to an HTML element
to listen for a specific event (such as a mouse click, keypress, or
page load) and trigger a function when the event occurs. The
basic syntax for adding an event listener is:

element.addEventListener(event, function, useCapture);

● element: The HTML element that we want to attach the


event listener to.
● event: The name of the event that we want to listen for
(e.g., "click", "keypress", "load", etc.).
● function: The function that should be executed when
the event is triggered.
● useCapture: An optional parameter that indicates
whether the event should be captured or not.

Event Handling
When an event is triggered, the function that we assigned to
the event listener will be executed. This function is called an
event handler. In the event handler, we can perform any action
that we want, such as changing the text of an element, hiding
an element, or showing a popup message.

element.addEventListener('click', function() {
// Do something when the element is clicked
});

Page 135
In the above example, we're adding an event listener to an
HTML element (which we'll refer to as element). We're listening
for the "click" event, and when that event occurs, we're
executing an anonymous function that performs some action.

Event Propagation
Events in JavaScript propagate from the top of the DOM tree to
the bottom. This means that when an event is triggered on an
element, it will first be handled by that element, then by its
parent element, and so on, until it reaches the top of the tree
(which is usually the window object).

Sometimes, we don't want an event to propagate all the way


up the DOM tree. We can prevent this using the
stopPropagation() method.

element.addEventListener('click', function(event) {
event.stopPropagation();
// Do something when the element is clicked
});

In the above example, we're adding an event listener to an


HTML element (which we'll refer to as element). We're listening
for the "click" event, and when that event occurs, we're
executing a function that calls stopPropagation() on the event
object (which we've named event). This prevents the event
from propagating any further up the DOM tree.

The Event Object


The event object is a crucial component of handling events in
JavaScript. When an event occurs, such as a user clicking a
button or scrolling the page, the browser creates an event
object that contains information about the event. This object is

Page 136
then passed to the callback function that is triggered by the
event.

The event object provides developers with a wealth of


information about the event, such as the type of event, the
element that triggered the event, and the position of the
mouse pointer when the event occurred. Developers can use
this information to create more robust and interactive web
applications.

Let's take a look at an example to see how the event object


works in practice. Say we have a button on our webpage that
we want to add an event listener to. We can use the
addEventListener() method to do this, like so:

const button = document.getElementById('myButton');

button.addEventListener('click', (event) => {


console.log(event.type); // logs 'click'
console.log(event.target); // logs the button element
});

In this example, we're listening for a 'click' event on the button


element. When the button is clicked, the callback function is
executed, and the event object is passed as an argument. We
can then use the event object to log information about the
event to the console, such as the type of event and the
element that triggered it.

The event object is an essential tool for JavaScript developers


working with web applications. By understanding how to
access and use the information provided by the event object,
developers can create more engaging and interactive user
experiences.

Page 137
The Event Object Applied
In the previous section, we learned about the event object and
how it can be used to access information about the event that
was triggered. Let's apply this knowledge to an example where
multiple elements use the same event listener callback
function, and the event.target property is used to determine
which element was clicked.

Suppose we have three buttons on a page, and we want to add


a click event listener to each of them that will change the color
of the text inside the clicked button. We can use a single
callback function for all three buttons, and use the event.target
property to determine which button was clicked. Here's
example code:

HTML
<button id="button1">Button 1</button>
<button id="button2">Button 2</button>
<button id="button3">Button 3</button>

JavaScript
function changeTextColor(event) {
const targetButton = event.target;
if (event.shiftKey) {
targetButton.style.color = "blue";
} else {
targetButton.style.color = "red";
}
}

const button1 = document.getElementById("button1");


const button2 = document.getElementById("button2");
const button3 = document.getElementById("button3");

button1.addEventListener("click", changeTextColor);

Page 138
button2.addEventListener("click", changeTextColor);
button3.addEventListener("click", changeTextColor);

In this example, we create a changeTextColor function that


takes in an event object as its argument. Inside the function,
we access the event.target property to get a reference to the
button that was clicked. We then use an if statement to check
if the shift key was pressed when the button was clicked. If it
was, we set the text color of the button to blue. Otherwise, we
set it to red.

We then use document.getElementById() to get references to


each of the three buttons, and use addEventListener() to attach
the changeTextColor function as the event listener for the click
event on each button.

When a button is clicked, the changeTextColor function is


called with an event object that contains information about
the click event. By accessing the event.target property, we can
determine which button was clicked and modify its text color
accordingly. We also use the event.shiftKey property to check if
the shift key was pressed when the button was clicked,
allowing us to change the text color based on the user's input.

Code Exercises
Exercise 8.1: Accessing and Modifying DOM Elements
Create a HTML page that contains a heading, paragraph and
button elements. Use JavaScript to access each element by its
ID and modify its text content. When the button is clicked,
change the text content of the heading and paragraph to
something else.

Requirements:
● Create an HTML file with a heading, paragraph, and
button element

Page 139
● Add IDs to the heading, paragraph, and button
elements
● Use JavaScript to access each element by its ID and
modify its text content
● Add an event listener to the button element so that it
changes the text content of the heading and paragraph
when clicked

Exercise 8.2: Modifying CSS


Create a HTML page that contains a button element. Use
JavaScript to change the background color of the page when
the button is clicked.

Requirements:
● Create an HTML file with a button element
● Add an ID to the button element
● Use JavaScript to add an event listener to the button
element
● When the button is clicked, change the background
color of the page using CSS

Exercise 8.3: Responding to Mouse Events


Create a HTML page that contains a button element. Use
JavaScript to change the text content of the button element
when the mouse is over it and when the mouse leaves the
button.

Requirements:
● Create an HTML file with a button element
● Add an ID to the button element
● Use JavaScript to add event listeners to the button
element for "mouseover" and "mouseout" events
● When the mouse is over the button, change its text
content
● When the mouse leaves the button, change its text
content back to its original text

Page 140
Exercise 8.4: Responding to Keyboard Events
Create a HTML page that contains a text input element. Use
JavaScript to change the text content of a paragraph element
when a key is pressed in the text input.

Requirements:
● Create an HTML file with a text input element and a
paragraph element
● Add IDs to the text input and paragraph elements
● Use JavaScript to add an event listener to the text input
element for "keydown" events
● When a key is pressed in the text input, change the text
content of the paragraph element to the value of the
text input

Exercise 8.5: Modifying HTML Attributes


Create a HTML page that contains an image element. Use
JavaScript to change the source attribute of the image when a
button is clicked.

Requirements:
● Create an HTML file with an image element and a
button element
● Add an ID to the image and button elements
● Use JavaScript to add an event listener to the button
element
● When the button is clicked, change the source attribute
of the image to a new image URL

Exercise 8.6: Creating and Removing Elements


Create a HTML page that contains a button element. Use
JavaScript to create a new paragraph element when the
button is clicked, and remove the paragraph element when the
button is clicked again.

Requirements:
● Create an HTML file with a button element

Page 141
● Add an ID to the button element
● Use JavaScript to add an event listener to the button
element
● When the button is clicked, create a new paragraph
element with some text content and add it to the page
● When the button is clicked again, remove the
paragraph element from the page

Exercise 8.7: Event Bubbling and Delegation


Create a HTML page that contains a list of items. Use JavaScript
to add event listeners to the list items so that they change
color when clicked. Use event bubbling and delegation to
minimize the amount of event listeners needed.

Exercise 8.8: Interactive Form Validation


Create a form with the following fields: name, email, phone
number, and password. Use the appropriate HTML input types
and attributes to ensure that the user enters valid data for each
field.

Then, use JavaScript to add event listeners to each field that


trigger a function to check the user's input. The function
should do the following:

● Check that the name field is not empty and contains


only letters and spaces.
● Check that the email field is a valid email address
format.
● Check that the phone number field is a valid phone
number format.
● Check that the password field is at least 8 characters
long and contains at least one uppercase letter, one
lowercase letter, and one number.

If any of the checks fail, display an error message next to the


corresponding field. If all checks pass, display a success
message.

Page 142
Bonus: Add a "submit" button that only becomes active once
all fields pass validation. When the user clicks the submit
button, display a message thanking them for their submission.

Note: You can use regular expressions to help with the


validation checks.
(https://www.tutorialspoint.com/javascript/javascript_regexp_o
bject.htm)

Exercise 8.9: Click Counter


Create an HTML file that contains a button element with an id
attribute of "counterBtn". Then, create a JavaScript file that
adds a click event listener to the button. When the button is
clicked, a counter should increment by 1 and the new value
should be displayed on the webpage. Use the event object to
access the button element and modify its innerHTML property.

Exercise 8.10: Image Gallery


Create an HTML file that contains three image elements with
unique id attributes. Then, create a JavaScript file that adds a
click event listener to each image. When an image is clicked, it
should be enlarged to 200% of its original size. Use the event
object to access the clicked image element and modify its
width and height properties. When the shift key is held down
while clicking an image, the image should shrink back to its
original size. Use the event object to determine if the shift key
is pressed.

Critical Points
Introduction to the DOM:
● The DOM is a hierarchical representation of an HTML
document that allows for dynamic changes to web
pages through JavaScript.
● JavaScript can be used to access and modify DOM
elements, including their content and style.

Page 143
Accessing DOM Elements:
● The most common way to access a DOM element is by
its ID using document.getElementById().
● There are other ways to access DOM elements, such as
by their class name, tag name, or relationship to other
elements.
● It's important to use the correct syntax when accessing
elements to avoid errors.

Modifying DOM Elements:


● JavaScript can be used to modify the content,
attributes, and style of DOM elements.
● Modifying content involves changing the text, HTML, or
value of an element.
● Modifying attributes involves changing the properties
of an element, such as its ID or class.
● Modifying style involves changing the visual
appearance of an element, such as its color or font.

Modifying CSS:
● JavaScript can be used to modify CSS properties of
DOM elements.
● Styles can be modified by changing the value of the
style property or by modifying individual CSS properties
using the element's style object.
● It's important to be careful when modifying CSS, as it
can affect the layout and functionality of a web page
.
Responding to Events:
● JavaScript can be used to respond to user interactions,
such as clicks, mouse movements, and key presses.
● Event listeners are used to trigger JavaScript functions
in response to specific events.
● Events can be handled with callback functions that are
executed when the event occurs.

The Event Object:

Page 144
● The event object contains information about the event
that was triggered, such as the type of event, the target
element, and any additional data.
● The event object can be used to access and modify
DOM elements in response to events.
● Event propagation and delegation can be used to
handle events efficiently and minimize the number of
event listeners needed.

The FAQ
Q: What is the DOM?
A: The Document Object Model (DOM) is a programming
interface for web documents. It represents the page so that
programs can change the document structure, style, and
content.

Q: How do I access DOM elements?


A: You can access DOM elements using JavaScript methods
such as getElementById(), getElementsByClassName(),
getElementsByTagName(), and querySelector().

Q: How can I modify the text content of a DOM element?


A: You can modify the text content of a DOM element using
JavaScript properties such as innerHTML, textContent, and
innerText.

Q: How can I modify the CSS of a DOM element?


A: You can modify the CSS of a DOM element using JavaScript
methods such as style.setProperty(), style.backgroundColor,
and style.fontSize.

Q: How can I respond to user events, such as clicks or


keypresses?
A: You can add event listeners to DOM elements using
JavaScript methods such as addEventListener().

Page 145
Q: What is the event object?
A: The event object is a JavaScript object that contains
information about the event that has occurred, such as the
target element and the type of event.

Q: How can I prevent default behavior or stop event


propagation?
A: You can prevent default behavior or stop event propagation
using methods such as preventDefault() and
stopPropagation().

Q: What are some best practices for DOM manipulation?


A: Some best practices for DOM manipulation include avoiding
excessive DOM manipulation, using efficient selectors, and
using event delegation to minimize the number of event
listeners.

Page 146
Section 9: Asynchronous
JavaScript
Up until now, we've been focusing on synchronous code - that
is, code that runs one line at a time in the order that it's written.
However, in the real world of web development, we often need
to work with asynchronous code - code that runs out of order
or at a later time, such as when we're waiting for data to be
fetched from a server.

Asynchronous programming can seem like a daunting topic at


first, but don't worry - we'll break it down into manageable
pieces and help you understand the concepts step by step.
We'll start by introducing you to callback functions, which are a
way to handle asynchronous code in JavaScript. Then, we'll
move on to the newer and more powerful concepts of
promises and async/await. Finally, we'll show you how to use
the Fetch API to make HTTP requests and retrieve data from
servers. So buckle up and get ready to take your JavaScript
skills to the next level!

Callback functions
In JavaScript, a callback function is a function that is passed as
an argument to another function and is called inside that
function. Callback functions are commonly used in
asynchronous programming to handle events that take time to
complete, such as network requests or file input/output.

The beauty of callbacks is that they allow you to write


asynchronous code without blocking the main thread of
execution. Instead, the callback function is executed after the
task has been completed, allowing other code to continue
running in the meantime.

Page 147
Callback functions can be a bit tricky to work with, as they
often require nesting and can lead to what is known as
"callback hell." However, with proper coding practices and the
use of other asynchronous techniques like Promises and
async/await, callback functions can be a powerful tool for
building efficient and scalable applications.

Passing Functions as Arguments


The most common use case for callback functions is passing
them as arguments to other functions. Here is an example of a
function that takes a callback function as an argument:

function add(a, b, callback) {


const sum = a + b;
callback(sum);
}

function logSum(sum) {
console.log(`The sum is ${sum}.`);
}

add(5, 10, logSum);


// Output: The sum is 15.

In this example, the add function takes two numbers as


arguments and a callback function. The add function then
calculates the sum of the two numbers and passes it to the
callback function. The logSum function is then passed as the
callback function and logs the sum to the console.

Nested Callbacks
One of the biggest challenges with callback functions is
dealing with nested callbacks. This is when a function that
takes a callback function as an argument is itself passed as an
argument to another function that also takes a callback

Page 148
function as an argument. This can quickly lead to nested
functions that are difficult to read and maintain.

Here is an example of nested callbacks:


function getData(callback) {
// Simulate a network request that takes 2 seconds to
complete
setTimeout(() => {
const data = { name: "John", age: 30 };
callback(data);
}, 2000);
}

function displayData(data) {
// Simulate another network request that takes 1
second to complete
setTimeout(() => {
console.log(`Name: ${data.name}, Age:
${data.age}`);
}, 1000);
}

getData(displayData);
// Output after 3 seconds: Name: John, Age: 30

In this example, the getData function takes a callback function


as an argument and simulates a network request that takes 2
seconds to complete. The displayData function is then passed
as the callback function and simulates another network
request that takes 1 second to complete. The output is logged
to the console after 3 seconds.

As you can see, this code can quickly become hard to read and
maintain. To avoid this, you can use other asynchronous
techniques like Promises or async/await, which we will cover in
the next sections.

Page 149
Promises
Promises are a powerful tool for handling asynchronous
JavaScript. They provide a way to work with asynchronous
operations in a more structured and predictable way. In this
section, we'll cover the basics of promises and how to use them
in your code.

Introduction to Promises
A promise is an object that represents a value that may not be
available yet, but will be at some point in the future. It is a
placeholder for a value that will be resolved eventually.
Promises provide a way to handle asynchronous code in a
more elegant way. They make it easier to manage and chain
together multiple asynchronous operations.

Creating a Promise
A promise is created using the Promise constructor function.
The constructor function takes a single argument, a callback
function, which takes two arguments: resolve and reject. The
resolve function is called when the promise is successfully
fulfilled, and the reject function is called when the promise is
rejected.

const promise = new Promise((resolve, reject) => {


// async operation
const result = someAsyncFunction();
if (result) {
resolve(result);
} else {
reject("Error occurred");
}
});

Page 150
Consuming a Promise
Once a promise is created, you can consume its result using
the then() method. The then() method takes two functions as
arguments: a success handler and an error handler. The
success handler is called when the promise is fulfilled, and the
error handler is called when the promise is rejected.

promise.then(
(result) => {
console.log(result);
},
(error) => {
console.log(error);
}
);

Chaining Promises
One of the most powerful features of promises is the ability to
chain them together. This allows you to execute multiple
asynchronous operations in sequence, without having to nest
callbacks.

const promise1 = new Promise((resolve) => {


setTimeout(() => {
resolve("Hello");
}, 1000);
});

const promise2 = (data) => {


return new Promise((resolve) => {
setTimeout(() => {
resolve(`${data} World`);
}, 1000);
});
};

Page 151
promise1
.then((result) => {
return promise2(result);
})
.then((result) => {
console.log(result);
});

In this example, we create two promises. The first one waits for
1 second and resolves with the string "Hello". The second
promise takes a parameter, appends " World" to it, and resolves
with the new string. We then chain the promises together
using the then() method. The first promise resolves with "Hello",
which is passed as a parameter to the second promise. The
second promise appends " World" to it and resolves with "Hello
World", which is finally printed to the console.

Error Handling with Promises


Error handling is an important part of any asynchronous
operation. Promises provide an elegant way to handle errors
using the catch() method. The catch() method is called when a
promise is rejected and takes an error handler as an argument.

const promise = new Promise((resolve, reject) => {


// async operation
const result = someAsyncFunction();
if (result) {
resolve(result);
} else {
reject("Error occurred");
}
});

promise.then((result) => {

Page 152
console.log(result);
}).catch((error) => {
console.log(error);
});

In this example, if the promise is rejected, the error handler will


be called and the error message will be printed to the console.

Async/await
Asynchronous code can be hard to read and maintain due to
its nested and sometimes convoluted structure. Fortunately,
ES2017 introduced a new syntax called async/await that
simplifies the writing of asynchronous code. It allows you to
write asynchronous code in a way that looks and behaves like
synchronous code, making it easier to read, write, and debug.

What is Async/Await?
Async/await is a syntactic sugar built on top of Promises that
allows you to write asynchronous code using a more familiar
syntax. It allows you to write asynchronous functions that look
and behave like synchronous functions. Async/await is built on
top of Promises, so it is important to understand Promises
before diving into async/await.

Async Functions
Async functions are functions that return a Promise. They are
declared using the async keyword before the function
declaration. Async functions can contain one or more await
expressions, which pause the execution of the function until
the Promise is resolved or rejected.

Here is an example of an async function that simulates a


network request using a Promise:

Page 153
async function fetchData() {
const response = await
fetch('https://jsonplaceholder.typicode.com/todos/1');
const data = await response.json();
return data;
}

In this example, the fetchData function returns a Promise that


resolves to the JSON data returned by the API. The await
keyword is used to pause the execution of the function until
the Promise returned by the fetch method resolves. Once the
Promise resolves, the data is extracted from the response by
calling the json method on the response object. The await
keyword is used again to pause the execution of the function
until the Promise returned by the json method resolves.

Error Handling
One of the benefits of using async/await is that it simplifies
error handling in asynchronous code. You can use try/catch
blocks to catch any errors that occur in the Promise chain. Here
is an example:

async function fetchData() {


try {
const response = await
fetch('https://jsonplaceholder.typicode.com/todos/1');
const data = await response.json();
return data;
} catch (error) {
console.log(error);
}
}

In this example, if any errors occur in the Promise chain, they


will be caught by the catch block and logged to the console.

Page 154
Using Async/Await with Promise.all
Async/await can also be used with Promise.all to execute
multiple Promises in parallel. The Promise.all method takes an
array of Promises and returns a Promise that resolves to an
array of resolved values from the input Promises. Here is an
example:

async function fetchAllData() {


const promise1 =
fetch('https://jsonplaceholder.typicode.com/todos/1');
const promise2 =
fetch('https://jsonplaceholder.typicode.com/todos/2');
const promise3 =
fetch('https://jsonplaceholder.typicode.com/todos/3');
const [data1, data2, data3] = await
Promise.all([promise1, promise2, promise3])
.then((responses) =>
Promise.all(responses.map((response) =>
response.json())));
return [data1, data2, data3];
}

In this example, the Promise.all method is used to execute


multiple Promises in parallel. Once all the Promises have
resolved, the then method is called to extract the JSON data
from each response object. The await keyword is used to pause
the execution of the function until all Promises have resolved
and the data has been extracted. Finally

Using the Fetch API for HTTP requests


In modern web development, it's common to make HTTP
requests to external APIs in order to retrieve data. The fetch
function is a built-in JavaScript method that makes it easy to
send HTTP requests and handle the responses.

Page 155
Note: We’re using the Open Weather Map API for the next
series of examples. You may need to obtain your own key and
insert it into the code where indicated. You can obtain your API
key at https://openweathermap.org/api.

Sending a GET Request with Fetch


The simplest way to use fetch is to send a GET request to a URL
and retrieve the response. Here's an example:

fetch('https://api.openweathermap.org/data/2.5/weather?
q=Seattle&appid=YOUR_APP_ID')
.then(response => response.json())
.then(data => console.log(data));

In this example, we're sending a GET request to the


OpenWeatherMap API to retrieve the current weather in
Seattle. We pass the API endpoint URL to the fetch function,
which returns a Promise that resolves with a Response object.

We then call the json() method on the Response object to


parse the response as JSON. This returns another Promise that
resolves with the parsed data.

Finally, we use another .then() block to log the parsed data to


the console.

Handling Errors with Fetch


When making API requests, it's important to handle errors
gracefully. Here's an example of how to use fetch to handle
errors:

fetch('https://api.openweathermap.org/data/2.5/weather?
q=Seattle&appid=YOUR_APP_ID')
.then(response => {

Page 156
if (!response.ok) {
throw new Error(response.status);
}
return response.json();
})
.then(data => console.log(data))
.catch(error => console.error(error));

In this example, we're still sending a GET request to the


OpenWeatherMap API. However, we're also checking if the
response was successful using the ok property on the
Response object. If the response was not successful, we throw
an error with the HTTP status code.

We use the .catch() method to handle any errors that occur


during the request or parsing of the response.

Using Async/Await with Fetch


Just like with callback functions and Promises, you can also use
async/await with fetch. Here's an example:

async function getWeather(city) {


const response = await
fetch(`https://api.openweathermap.org/data/2.5/weather?
q=${city}&appid=YOUR_APP_ID`);
if (!response.ok) {
throw new Error(response.status);
}
const data = await response.json();
return data;
}

getWeather('Seattle')
.then(data => console.log(data))
.catch(error => console.error(error));

Page 157
In this example, we've defined an async function called
getWeather that takes a city parameter. Inside the function, we
use await to wait for the response from fetch, and then check if
it was successful.

We then parse the response using await response.json() and


return the resulting data.

Outside of the function, we call getWeather('Seattle') and use


.then() and .catch() to handle the results and any errors that
occur.

Overall, fetch is a powerful tool for making HTTP requests and


retrieving data from external APIs. By using Promises or
async/await, we can handle the responses and any errors that
occur in a clear and concise way.

Parsing XML data from APIs


Some APIs return data in XML format, which is different from
the more commonly used JSON format. In order to work with
XML data, we need to parse it into a JavaScript object that we
can work with. There are several JavaScript libraries available
for parsing XML, but in this section, we will use the built-in
DOMParser object.

To demonstrate how to parse XML data, let's use the Goodreads


API, which provides information about books. We can use the
following code to make a request to the API and get the XML
data:

const API_KEY = 'your_api_key_here';


const bookId = 1234;

fetch(`https://www.goodreads.com/book/show/${bookId}.xm
l?key=${API_KEY}`)
.then(response => response.text())

Page 158
.then(data => {
const parser = new DOMParser();
const xml = parser.parseFromString(data,
'application/xml');
console.log(xml);
})
.catch(error => console.error(error));

In this code, we use the fetch function to make a request to the


Goodreads API, passing in our API key and the ID of the book
we want to retrieve. We then use the text() method to extract
the XML data from the response. Once we have the XML data,
we create a new DOMParser object and use the
parseFromString method to convert the XML data into a
Document object. Finally, we log the Document object to the
console.

Now that we have the XML data in a Document object, we can


access the data using standard DOM traversal methods like
querySelector and getElementsByTagName. For example, let's
say we want to extract the title and author of the book. We can
use the following code to do that:

const title = xml.querySelector('title').textContent;


const author = xml.querySelector('author
name').textContent;
console.log(title, author);

In this code, we use the querySelector method to select the


title and author name elements from the Document object,
and then use the textContent property to get the text content
of those elements.

Note that when working with XML data, we need to be mindful


of namespaces and the structure of the XML document. The
DOMParser object also has some limitations when it comes to

Page 159
parsing large XML documents, so for more complex scenarios,
it may be necessary to use a more specialized XML parsing
library.

Parsing JSON Data Returned from an API


JSON, or JavaScript Object Notation, is a lightweight data
interchange format that is widely used for APIs. It is easy to
read and write for both humans and machines. JavaScript
provides built-in functions to parse JSON data into JavaScript
objects, allowing you to easily manipulate the data and use it in
your web applications.

To demonstrate parsing JSON data, let's use the


openweathermap API to retrieve current weather data for a
specific city. First, you will need to obtain an API key from the
openweathermap website. Once you have an API key, you can
make a request to the API using the fetch() function:

fetch(`https://api.openweathermap.org/data/2.5/weather?q=Lo
ndon&appid=${apiKey}`)
.then(response => response.json())
.then(data => console.log(data));

In this example, we are making a fetch() request to the


openweathermap API to retrieve the weather data for London.
We are also passing in our API key using template literals.

The fetch() function returns a promise that resolves to the


response from the API. We then use the json() method to parse
the response into a JavaScript object. Finally, we log the object
to the console to verify that we have successfully parsed the
JSON data.

Once you have the weather data as a JavaScript object, you can
manipulate it and use it in your web application as needed. For
example, you could display the current temperature or weather

Page 160
conditions on your website. JSON data is commonly used with
APIs, so it's important to know how to parse it in JavaScript.

Code Exercise

Exercise 9.1: API Application


In this exercise, you will use the Random User API to retrieve
information about a randomly generated user and display it on
a web page.

Requirements:

1. Create an HTML file with a button and a div element.


2. Use JavaScript to add an event listener to the button
element that triggers a function when clicked.
3. When the button is clicked, use the Fetch API to make a
request to the Random User API to retrieve information
about a user.
4. Parse the response from the API as JSON.
5. Access the relevant information about the user (such as
their name, picture, and location) from the parsed JSON
response.
6. Use JavaScript to modify the text content and image
source of the div element to display the retrieved user
information.
7. Use CSS to style the div element with a border, padding,
and margin.

Bonus:
1. Add error handling to your code to display a message if
the API request fails.
2. Add a loading spinner or animation to the div element
while the API request is being made.
3. Add a refresh button that retrieves a new randomly
generated user and displays their information.

Page 161
Note: You will need to obtain an API key from the Random User
API website (https://randomuser.me/) to make requests to the
API.

Critical Points
Callback functions:
● Callback functions are functions that are passed as
arguments to other functions.
● They are commonly used in asynchronous JavaScript to
handle data once it is retrieved.
● They allow you to execute code after a task has
completed, without blocking the main thread.

Promises:
● Promises are a way to handle asynchronous code that is
easier to read and write than callbacks.
● They represent a value that may not be available yet,
but will be resolved at some point in the future.
● They have a then() method that allows you to chain
together multiple asynchronous operations.

Async/Await:
● Async/await is a way to write asynchronous code that
looks more like synchronous code.
● It uses the async keyword to indicate that a function is
asynchronous, and the await keyword to pause the
function until a promise is resolved.
● It makes asynchronous code easier to read and write
than callbacks and promises.

Using the Fetch API for HTTP Requests:


● The Fetch API is a modern JavaScript API for making
HTTP requests.
● It provides a more powerful and flexible way to make
requests than traditional methods like
XMLHttpRequest.

Page 162
● It returns a promise that resolves with the response
from the server.

The FAQ
Q: What are callback functions in JavaScript?
A: A callback function is a function that is passed as an
argument to another function and is called when the first
function completes its task. In the context of asynchronous
JavaScript, callback functions are often used to handle the
results of asynchronous operations.

Q: What is a promise in JavaScript?


A: A promise is an object that represents the eventual
completion (or failure) of an asynchronous operation and its
resulting value. Promises are used to handle asynchronous
operations in a more structured and easier-to-read way than
using just callbacks.

Q: What is async/await in JavaScript?


A: Async/await is a syntax for handling asynchronous
operations in JavaScript that allows developers to write
asynchronous code that looks more like synchronous code. The
async keyword is used to define an asynchronous function that
returns a promise, while the await keyword is used to wait for
the result of a promise within an async function.

Q: What is the Fetch API in JavaScript?


A: The Fetch API is a modern API for making HTTP requests in
JavaScript that provides a simpler and more flexible interface
than older APIs like XMLHttpRequest. It uses promises to
handle asynchronous operations and can be used to fetch
resources from remote servers like JSON data, images, or other
files.

Q: What is JSON and how is it used with APIs?

Page 163
A: JSON (JavaScript Object Notation) is a lightweight data
format that is commonly used for transmitting data between a
server and a web application. APIs often return data in the
form of JSON, which can be parsed and used by JavaScript
code to update the content of a web page dynamically.

Page 164
Section 10: JavaScript Tools and
Libraries
In this section, we will explore some of the most popular tools
and libraries used by JavaScript developers to simplify their
workflow and enhance their applications. We will begin by
discussing Node.js and npm, which are essential for server-side
JavaScript development and managing dependencies. We will
also cover Webpack and Babel, which are powerful tools for
bundling and transpiling JavaScript code, respectively.

Additionally, we will explore front-end frameworks such as


React, which allows developers to build complex user
interfaces with ease, and back-end frameworks such as
Express, which makes building server-side applications a
breeze. Finally, we will discuss testing frameworks like Jest and
Mocha, which help developers ensure the quality and
functionality of their code.

By the end of this section, you will have a solid understanding


of some of the most essential tools and libraries used in
modern JavaScript development, and be ready to take your
own projects to the next level. So let's get started!

Node.js and npm


Node.js is a runtime environment for JavaScript that allows you
to run JavaScript code outside of a web browser. NPM, short for
Node Package Manager, is a package manager for Node.js that
allows developers to easily install, update, and manage
packages for their projects. In this section, we'll cover the basics
of Node.js and NPM and show you how to get started.

Page 165
Installing Node.js and NPM
To get started with Node.js and NPM, you'll need to install
them on your computer. The easiest way to do this is by
downloading and installing the Node.js installer from the
official website. Once installed, you can use the node
command to run JavaScript code from the command line, and
the npm command to manage packages.

Creating a Node.js Project


To create a new Node.js project, you can use the npm init
command to create a new package.json file. This file contains
metadata about your project, as well as a list of dependencies
that your project requires. You can use the npm install
command to install packages and add them to your
package.json file.

Using Third-Party Packages


There are thousands of third-party packages available on NPM
that you can use to add functionality to your Node.js projects.
You can search for packages on the NPM website or by using
the npm search command. To use a package in your project,
simply install it using the npm install command and then
require() it in your code.

Here's an example of how to install the axios package and use


it to make an HTTP request:

// install the axios package


npm install axios

// require the axios package


const axios = require('axios');

// make an HTTP request


axios.get('https://jsonplaceholder.typicode.com/todos/1

Page 166
')
.then(response => {
console.log(response.data);
})
.catch(error => {
console.log(error);
});

In this example, we're using the axios package to make an


HTTP GET request to a JSON API and log the response data to
the console. As you can see, using third-party packages in
Node.js is easy and can save you a lot of time and effort.

That's a brief introduction to Node.js and NPM! In the next


sections, we'll cover some of the most popular tools and
libraries used in the JavaScript ecosystem, including Webpack,
Babel, React, Express, and testing frameworks like Jest and
Mocha.

Webpack and Babel


Webpack and Babel are two powerful tools that are commonly
used together in modern JavaScript development. Webpack is
a module bundler, which means it takes your code and all its
dependencies and packages them into a single, optimized file
for deployment. Babel is a transpiler that allows you to write
modern JavaScript and then compiles it into code that can be
understood by older browsers.

Installing and configuring Webpack and Babel can seem


daunting at first, but once you get the hang of it, it can make
your development process much smoother. Let's dive into each
tool and see how they work together.

Page 167
Installing Webpack and Babel
Before we can use Webpack and Babel, we need to install
them. We can do this easily using NPM, the Node.js package
manager.

First, let's install Webpack and its command line interface (CLI)
globally:

npm install -g webpack webpack-cli

Next, let's install Babel and some of its associated packages:

npm install --save-dev babel-loader @babel/core


@babel/preset-env webpack

The --save-dev flag tells NPM to add these packages to our


development dependencies, rather than our production
dependencies.

Configuring Webpack and Babel


Now that we have our tools installed, let's configure them.

First, we'll create a new file in the root of our project called
webpack.config.js. This file will contain our Webpack
configuration. Here's a basic example:

const path = require('path');

module.exports = {
entry: './src/index.js',
output: {
filename: 'main.js',
path: path.resolve(__dirname, 'dist')
},

Page 168
module: {
rules: [
{
test: /\.js$/,
exclude: /(node_modules)/,
use: {
loader: 'babel-loader',
options: {
presets: ['@babel/preset-env']
}
}
}
]
}
};

React and other front-end frameworks


React is a popular JavaScript library for building user interfaces.
It was developed by Facebook and is widely used by
companies like Netflix, Airbnb, and Dropbox. In this section,
we'll explore React and other front-end frameworks.

Introduction to React

React is a library that allows developers to create reusable UI


components. It uses a virtual DOM to efficiently render
changes to the user interface. React's component-based
architecture and one-way data flow make it easier to build
complex UIs.

Creating a React Component


A React component is a JavaScript class or function that
returns a piece of UI. To create a component, we can use the
React.createElement() function or JSX syntax. JSX is a syntax

Page 169
extension that allows us to write HTML-like syntax in our
JavaScript code.

// using React.createElement()
const element = React.createElement('h1', null, 'Hello,
world!');
ReactDOM.render(element,
document.getElementById('root'));

// using JSX
const element = <h1>Hello, world!</h1>;
ReactDOM.render(element,
document.getElementById('root'));

Rendering a Component
To render a component, we use the ReactDOM.render()
function. This function takes a component and a DOM element
as arguments and renders the component inside the DOM
element.

function App() {
return (
<div>
<h1>Hello, world!</h1>
<p>Welcome to my React app.</p>
</div>
);
}

ReactDOM.render(<App />,
document.getElementById('root'));

Page 170
Handling Events
React allows us to handle events in a declarative way using
props. We can define event handlers as methods on our
component and pass them as props to child components.

function Button(props) {
return (
<button onClick={props.onClick}>
{props.label}
</button>
);
}

class App extends React.Component {


handleClick() {
console.log('Button clicked!');
}

render() {
return (
<div>
<h1>Hello, world!</h1>
<Button label="Click me"
onClick={this.handleClick} />
</div>
);
}
}

ReactDOM.render(<App />,
document.getElementById('root'));

React is just one of many front-end frameworks available to


developers. Other popular frameworks include Angular and
Vue.js. Each framework has its own strengths and weaknesses,
so it's important to choose the one that best fits your project's
needs.

Page 171
Express and other back-end frameworks
In web development, the back-end refers to the server-side of
an application, responsible for processing data and returning it
to the client-side. One of the most popular back-end
frameworks for Node.js is Express. However, there are also other
great options to choose from, such as Koa and Hapi.

Installing Express
To get started with Express, you first need to install it through
npm, the package manager for Node.js. Open a terminal
window and run the following command:

npm install express

This command will install the latest version of Express and its
dependencies. You can also specify a specific version of Express
by adding @version_number to the end of the command.

Creating an Express Server


Once Express is installed, you can create a new server by
creating a new JavaScript file and requiring the Express
module. Here's an example:

const express = require('express');


const app = express();

app.get('/', (req, res) => {


res.send('Hello World!');
});

app.listen(3000, () => {
console.log('Server started on port 3000');
});

Page 172
In this example, we require the Express module and create a
new app instance. We then define a route for the root path '/'
using the app.get() method, which takes a callback function
with two parameters, req for the request and res for the
response. Finally, we start the server on port 3000 using the
app.listen() method and log a message to the console.

Handling Requests and Responses


Express provides a number of methods for handling different
types of HTTP requests, such as app.get() for GET requests and
app.post() for POST requests. You can also use middleware
functions to handle requests before they are processed by your
routes.

app.use(express.json()); // for parsing


application/json
app.use(express.urlencoded({ extended: true })); // for
parsing application/x-www-form-urlencoded

app.get('/', (req, res) => {


res.send('Hello World!');
});

app.post('/users', (req, res) => {


const user = req.body;
console.log(user);
res.send('User added successfully');
});

In this example, we use the express.json() and


express.urlencoded() middleware functions to parse JSON and
URL-encoded data in requests. We then define a route for the
'/users' path using the app.post() method, which takes a
callback function with the req and res parameters. We can
access the data sent in the request body through req.body.

Page 173
Using Other Back-end Frameworks
While Express is a popular choice for Node.js back-end
development, there are also other great options to choose
from. For example, Koa is a more lightweight alternative to
Express, focusing on a middleware-based approach. Hapi is
another option, providing a more structured and modular
approach to building back-end applications.

No matter which back-end framework you choose, make sure


to read the documentation and experiment with different
options to find the one that works best for your project.

Testing frameworks (Jest, Mocha, etc.)


Writing tests for your code can be a daunting task, but it's an
essential part of ensuring the quality and reliability of your
code. Luckily, there are several testing frameworks available for
JavaScript that can help simplify the process.

Jest and Mocha are two of the most popular testing


frameworks for JavaScript. Jest is a testing framework
developed by Facebook and is widely used for testing React
applications. Mocha, on the other hand, is a more
general-purpose testing framework that can be used for any
JavaScript project.

Writing Tests with Jest

Jest provides a simple and intuitive API for writing tests. Here's
an example of a test that checks if a function returns the
correct value:

function add(a, b) {
return a + b;
}

Page 174
test('adds two numbers', () => {
expect(add(1, 2)).toBe(3);
});

In this example, we define a function add that takes two


numbers and returns their sum. We then define a test case
using the test function provided by Jest. The test case checks if
add(1, 2) returns the value 3. We use the expect function to
define the expected value, and the toBe matcher to check if
the actual value matches the expected value.

Writing Tests with Mocha

Mocha provides a more flexible API for writing tests. Here's an


example of a test that uses Mocha's assert library to check if a
function returns the correct value:

const assert = require('assert');

function multiply(a, b) {
return a * b;
}

describe('multiply', () => {
it('should return the product of two numbers', () =>
{
assert.equal(multiply(2, 3), 6);
});
});

In this example, we define a function multiply that takes two


numbers and returns their product. We then define a test case
using Mocha's describe and it functions. The describe function
is used to group related test cases, while the it function is used
to define individual test cases. We use the assert library to
check if multiply(2, 3) returns the value 6.

Page 175
Code Coverage

One of the key metrics for measuring the effectiveness of your


tests is code coverage. Code coverage measures the
percentage of your code that is covered by tests. There are
several tools available for measuring code coverage in
JavaScript, such as Istanbul and Jest's built-in coverage
reporting.

// .babelrc
{
"plugins": ["istanbul"]
}

// package.json
{
"scripts": {
"test": "jest --coverage"
}
}

In this example, we configure Babel to use the istanbul plugin


for code coverage instrumentation. We then configure Jest to
generate coverage reports using the --coverage flag. This will
generate a coverage report in the coverage directory of your
project.

Testing is a critical part of the software development process,


and there are several testing frameworks available for
JavaScript that can help simplify the process. Jest and Mocha
are two popular options, each with their own strengths and
weaknesses. It's important to choose a testing framework that
best fits your project's needs. Additionally, measuring code
coverage can help you identify areas of your code that may
need more thorough testing.

Page 176
Critical Points
Node.js and npm:
● Node.js is a JavaScript runtime built on Chrome's V8
engine.
● npm is the package manager for Node.js and is used to
install and manage dependencies.
● Node.js can be used for server-side development,
command-line tools, and build tools.
● The package.json file is used to manage project
dependencies and configuration.

Webpack and Babel:


● Webpack is a module bundler used for front-end
development that helps manage dependencies and
create production-ready code.
● Babel is a tool that converts modern JavaScript code to
code compatible with older browsers.
● Webpack and Babel are often used together in modern
web development.
● Webpack can also be used for server-side development.

React and other front-end frameworks:


● React is a popular front-end framework for building
user interfaces using reusable components.
● Other front-end frameworks include Angular, Vue, and
Ember.
● Front-end frameworks provide tools for managing state,
handling events, and building responsive and dynamic
interfaces.
● The Virtual DOM is a concept used in React that helps
optimize updates to the UI.

Express and other back-end frameworks:


● Express is a popular back-end framework for building
web applications with Node.js.

Page 177
● Other back-end frameworks include Koa, Hapi, and
Nest.
● Back-end frameworks provide tools for handling
routing, middleware, and serving data to the front-end.
● The Model-View-Controller (MVC) pattern is often used
in back-end development.

Testing frameworks (Jest, Mocha, etc.):


● Testing frameworks are used to write and run tests for
JavaScript code.
● Jest is a popular testing framework for React
applications.
● Mocha is a flexible testing framework that can be used
for both front-end and back-end development.
● Testing frameworks provide tools for writing and
running unit tests, integration tests, and end-to-end
tests.

The FAQ
Q: What is Node.js, and why is it important?
A: Node.js is a JavaScript runtime built on the Chrome V8
engine. It allows developers to run JavaScript on the
server-side, which means they can use the same language on
both the client and server. Node.js also includes a built-in
package manager called npm, which makes it easy to manage
dependencies and share code with other developers.

Q: What are Webpack and Babel, and how are they used in
JavaScript development?
A: Webpack is a module bundler that allows developers to
organize and package their code for deployment to a
production environment. Babel is a JavaScript compiler that
allows developers to use the latest language features, even if
they aren't supported by all browsers. Together, Webpack and

Page 178
Babel make it easier to write and deploy complex JavaScript
applications.

Q: What is React, and why is it popular?


A: React is a JavaScript library for building user interfaces. It is
popular because it allows developers to build complex,
interactive applications using a declarative syntax and a
component-based architecture. React also includes features
like server-side rendering, which can improve application
performance and SEO.

Q: What is Express, and how is it used in back-end


development?
A: Express is a popular Node.js framework for building web
applications and APIs. It provides a simple, yet powerful set of
features for routing, middleware, and templating, which can
make it easier to build robust, scalable back-end systems.

Q: What are testing frameworks like Jest and Mocha, and why
are they important?
A: Testing frameworks like Jest and Mocha provide a way for
developers to write automated tests for their code. These tests
can help ensure that code is working correctly, even as it is
updated or modified. Testing frameworks also make it easier to
catch and fix bugs before they make it to production, which
can save time and improve the overall quality of an application.

Page 179
Section 11: JavaScript Projects
Congratulations on making it to the end of the JavaScript
Workbook! By now, you should have a solid understanding of
the fundamentals of JavaScript, from variables and data types
to functions and objects. But what comes next? Where do you
go from here?

That's where the project section comes in. In this section, we'll
be providing you with a number of suggested projects that you
can work on to solidify your knowledge and take your
JavaScript skills to the next level. These projects will range from
small, bite-sized exercises to larger, more complex projects that
will challenge you and push you to grow as a developer.

Don't worry if you don't know where to start or feel


overwhelmed by the prospect of building a full-fledged project
on your own. We'll be providing detailed instructions and
guidance every step of the way, so you'll never be left
wondering what to do next.

And don't forget, the most important thing is to have fun!


Programming is a creative, rewarding pursuit, and we want you
to enjoy every step of the journey. So get ready to flex those
coding muscles, make some cool stuff, and let's dive into the
project section of the JavaScript Workbook!

Project: Weather App


Description: Create a web app that displays the current
weather for a given location. Users can enter the name of a city
or zip code to retrieve the current temperature, humidity, and
wind speed.
Requirements:

Page 180
● Use a weather API such as OpenWeatherMap or
Weather Underground
● Allow users to input a location and retrieve weather
data
● Display the current temperature, humidity, and wind
speed
● Style the app using CSS

Resources:
OpenWeatherMap API: https://openweathermap.org/api
Weather Underground API:
https://www.wunderground.com/weather/api

Project: To Do List
Description: Create a simple todo list app that allows users to
add and remove items. The app should display a list of all items
and allow users to mark items as complete.

Requirements:
● Allow users to add new items to the todo list
● Allow users to remove items from the todo list
● Allow users to mark items as complete
● Display a list of all items

Resources:
localStorage API:
https://developer.mozilla.org/en-US/docs/Web/API/Window/loc
alStorage

Project: Calculator
Description: Create a basic calculator app that allows users to
perform basic arithmetic operations.

Requirements:

Page 181
● Display a basic calculator interface with buttons for
numbers and operations
● Allow users to perform addition, subtraction,
multiplication, and division
● Display the result of each calculation

Project: Random Quote Generator


Description: Create an app that displays a random quote each
time the user refreshes the page.

Requirements:
● Use a quote API such as Quotes REST API or forismatic
API
● Display a random quote each time the user refreshes
the page
● Allow users to share the quote on social media

Resources:
● Quotes REST API: https://quotes.rest/
● forismatic API: https://forismatic.com/en/api/

Project: Memory Game


Description: Create a memory game where users try to match
pairs of cards.

Requirements:
● Display a grid of cards with hidden images
● Allow users to click on cards to reveal their images
● Keep track of which cards have been revealed
● Allow users to match pairs of cards
● Display a message when the game is over

Page 182
Project: Hangman
Description: Create a hangman game where users try to guess
a hidden word by guessing letters one at a time.

Requirements:
● Display a series of blanks representing the hidden word
● Allow users to guess letters one at a time
● Keep track of which letters have been guessed
● Display the guessed letters and the blanks for the
hidden word
● Display a message when the game is over

Project: Recipe App


Description: Create a recipe app where users can search for
recipes based on ingredients or keywords. Users should be able
to view recipe details such as ingredients, instructions, and
nutritional information.

Requirements:
● Use an API to retrieve recipe data
● Allow users to search for recipes based on keywords or
ingredients
● Display recipe details including ingredients,
instructions, and nutritional information
● Allow users to save and organize their favorite recipes
● Use CSS to style the app

APIs and resources:


● Spoonacular API: https://spoonacular.com/food-api
● Edamam API:
https://developer.edamam.com/edamam-docs-nutrition
-api
● Food2Fork API: https://www.food2fork.com/about/api
● Bootstrap framework: https://getbootstrap.com/

Page 183
Project: BART Transit Tracker
Description:
Create a real-time transit tracker that allows users to check the
location of BART trains in the San Francisco Bay Area.

Requirements:
● Display a map of the BART system
● Allow users to select a station to view real-time
departures and arrivals
● Display the next few trains departing and arriving at the
selected station, including their estimated arrival times
● Highlight the selected station on the map
● Update train locations and estimated arrival times in
real-time
● Allow users to filter train arrivals and departures by
destination, line, and direction
● Provide clear instructions for using the app

Resources:
● BART API documentation:
https://api.bart.gov/docs/overview/index.aspx
● Mapbox API for displaying the map:
https://www.mapbox.com/
● jQuery or another JavaScript library for making API calls
and updating the UI in real-time
● Bootstrap or another CSS framework for styling the app

Note: You will need to obtain an API key from BART to use their
API.

Project: Explore Your City


Description:
Create a web application that allows users to explore their city
using a mapping API. Users will be able to search for places of
interest such as restaurants, parks, museums, and other

Page 184
landmarks. The application should provide information about
each place of interest, such as hours of operation, reviews,
photos, and directions.

Requirements:

● Use a mapping API such as Google Maps, Mapbox, or


OpenStreetMap
● Implement search functionality for different types of
places of interest
● Display results in a visually appealing way using HTML
and CSS
● Provide detailed information about each place of
interest, including hours of operation, reviews, photos,
and directions
● Allow users to save places they are interested in to a list
or map
● Implement a feature for users to leave reviews and
ratings of the places they visit
● Make the application responsive to different screen
sizes

Resources:
● Google Maps API, Mapbox API, or OpenStreetMap API
● HTML and CSS for layout and styling
● JavaScript for dynamic functionality
● A backend database (e.g. Firebase or MongoDB) to store
user data and reviews
● Bootstrap or another front-end framework for
responsive design

Page 185
Excerise Soutions
Exercise 1.1: Simple variable manipulation

let myNumber = 42;


let myString = "Hello, world!";
console.log(myNumber);
console.log(myString);

Exercise 1.2: Using arithmetic operators

let x = 10;
let y = 5;
console.log(x + y); // 15
console.log(x - y); // 5
console.log(x * y); // 50
console.log(x / y); // 2

Exercise 1.3: Using comparison operators

let a = 10;
let b = 5;
console.log(a > b); // true
console.log(a <= b); // false
console.log(a === b); // false
console.log(a !== b); // true

Exercise 1.4: Using logical operators

let x = true;
let y = false;
console.log(x && y); // false
console.log(x || y); // true
console.log(!x); // false

Page 186
Exercise 1.5: Function creation

function multiply(num1, num2) {


return num1 * num2;
}

let result = multiply(5, 10);


console.log(result); // 50

Exercise 2.1: Basic Variable Declaration


let myString = "Hello, world!";
let myNumber = 42;
let myBoolean = true;
let myArray = [1, 2, 3];
let myObject = {name: "John", age: 30};

console.log(myString);
console.log(myNumber);
console.log(myBoolean);
console.log(myArray);
console.log(myObject);

Exercise 2.2: Concatenating Strings


let firstName = "John";
let lastName = "Doe";

console.log("Hello, " + firstName + " " + lastName +


"!");

Exercise 2.3: Declaring and Assigning Variables


let firstName = 'John';
let lastName = 'Doe';

console.log(firstName + ' ' + lastName);

Page 187
Exercise 2.4: Converting a String to a Number
let stringNumber = '7';
let numberValue = Number(stringNumber);

console.log(numberValue + 5);

Exercise 2.5: Manipulating an Array


let myArray = [1, 2, 3];

myArray.push(4);
myArray.shift();

console.log(myArray);

Exercise 2.6: Converting Between Data Types


let myBoolean = true;
let stringBoolean = String(myBoolean);

console.log(myBoolean);
console.log(stringBoolean);

Exercise 2.7: Complex Data Type Manipulation


let myObject = {
name: 'John Doe',
age: 30,
hobbies: ['reading', 'running', 'cooking']
};

console.log(myObject.hobbies[1]);

myObject.occupation = 'software engineer';

console.log(myObject);

Exercise 3.1: Odd or Even

Page 188
let number = prompt("Enter a number:");
if (number % 2 === 0) {
console.log("The number is even.");
} else {
console.log("The number is odd.");
}

Exercise 3.2: Grade Converter


let grade = prompt("Enter your grade (0-100):");
let letterGrade;
switch (true) {
case (grade >= 90 && grade <= 100):
letterGrade = "A";
break;
case (grade >= 80 && grade <= 89):
letterGrade = "B";
break;
case (grade >= 70 && grade <= 79):
letterGrade = "C";
break;
case (grade >= 60 && grade <= 69):
letterGrade = "D";
break;
default:
letterGrade = "F";
}
console.log(`Your letter grade is ${letterGrade}.`);

Exercise 3.3: For Loop


for (let i = 0; i < 5; i++) {
console.log(Math.floor(Math.random() * 10) + 1);
}

Exercise 3.4: While Loop


let num = 0;

Page 189
while (num !== 7) {
num = Math.floor(Math.random() * 10) + 1;
console.log(num);
}
console.log(num);

Exercise 3.5: Do/While Loop


let num;
do {
num = parseInt(prompt("Enter a number: "));
} while (num % 5 !== 0);
console.log(num);

Exercise 3.6: FizzBuzz


let num;
do {
num = parseInt(prompt("Enter a number: "));
} while (num % 5 !== 0);
console.log(num);

Exercise 3.7: Find the first even number


const numbers = [3, 7, 12, 5, 9, 2, 8, 4, 1];

for (let i = 0; i < numbers.length; i++) {


const number = numbers[i];
if (number % 2 === 0) {
console.log(number);
break;
}
}

Exercise 3.8: Skip over negative numbers


const numbers = [-1, 5, -3, 8, 2, -7, 10, -6];

Page 190
for (let i = 0; i < numbers.length; i++) {
const number = numbers[i];
if (number < 0) {
continue;
}
console.log(number);
}

Exercise 4.1: Calculator


function calculator(num1, num2, operator) {
switch(operator) {
case '+':
return num1 + num2;
case '-':
return num1 - num2;
case '*':
return num1 * num2;
case '/':
return num1 / num2;
default:
return "Invalid operator";
}
}

Exercise 4.2: Calculate the sum of two arrays


function arraySum(arr1, arr2) {
let sum = 0;
for (let num of arr1) {
sum += num;
}
for (let num of arr2) {
sum += num;
}
return sum;

Page 191
}

Exercise 4.3: Find the Longest Word


function findLongestWord(str) {
let words = str.split(' ');
let longestWordLength = 0;
for (let word of words) {
if (word.length > longestWordLength) {
longestWordLength = word.length;
}
}
return longestWordLength;
}

Exercise 4.4: Reverse a String


function reverseString(str) {
let reversed = '';
for (let i = str.length - 1; i >= 0; i--) {
reversed += str[i];
}
return reversed;
}

Exercise 4.5: Count Vowels


function countVowels(str) {
let count = 0;
for (let letter of str) {
if ('aeiouAEIOU'.includes(letter)) {
count++;
}
}
return count;
}

Exercises 4.6: Rewrite as Arrow Functions

Page 192
Function A
const multiplyByTwo = (num) => num * 2;

Function B
const addNumbers = (num1, num2) => num1 + num2;

Function C
const greeting = (name) => {
return "Hello, " + name + "!";
}

or
const greeting = (name) => `Hello, ${name}!`;

Exercise 4.7 Calculator


function calculator(num1, num2, operator) {
switch(operator) {
case '+':
return num1 + num2;
case '-':
return num1 - num2;
case '*':
return num1 * num2;
case '/':
return num1 / num2;
default:
return "Invalid operator";
}
}

Exercise 4.8: Calculate the sum of two arrays


function arraySum(arr1, arr2) {
let sum = 0;

Page 193
for(let num of arr1) {
sum += num;
}
for(let num of arr2) {
sum += num;
}
return sum;
}

Exercise 4.9: Find the Longest Word


function findLongestWord(str) {
let words = str.split(' ');
let maxLength = 0;
for(let word of words) {
if(word.length > maxLength) {
maxLength = word.length;
}
}
return maxLength;
}

Exercise 4.10: Reverse a String


function reverseString(str) {
let reversed = '';
for(let i = str.length - 1; i >= 0; i--) {
reversed += str[i];
}
return reversed;
}

Exercise 5.1: Array Practice


// Declare and initialize the array
const myArray = [1, 2, 3];

// Add the values 4 and 5 to the end of the array

Page 194
myArray.push(4, 5);

// Access the value 2 in the array and assign it to a


variable
const x = myArray[1];

// Use a for loop to iterate through the array and


print each value
for (let i = 0; i < myArray.length; i++) {
console.log(myArray[i]);
}

Exercise 5.2: Array Methods


// Declare and initialize the array
const fruits = ['apple', 'banana', 'cherry'];

// Add 'orange' to the end of the array


fruits.push('orange');

// Remove the last value from the array


fruits.pop();

// Add 'pear' to the beginning of the array


fruits.unshift('pear');

// Remove the first value from the array


fruits.shift();

// Remove 'banana' from the array


fruits.splice(1, 1);

// Create a new array containing 'apple' and 'cherry'


const newFruits = fruits.slice(0, 2);

Exercise 5.3: Array Iteration


// Declare and initialize the array

Page 195
const numbers = [1, 2, 3, 4, 5];

// Use the forEach() method to print each value to the


console
numbers.forEach(function(number) {
console.log(number);
});

Exercise 5.4: Array Mapping


// Declare and initialize the array
const numbers = [1, 2, 3, 4, 5];

// Use the map() method to create a new array


containing the squares of the numbers array
const squares = numbers.map(function(number) {
return number * number;
});

// Print the new array to the console


console.log(squares);

Exercise 5.5: Array Filtering


// Declare and initialize the array
const numbers = [1, 2, 3, 4, 5];

// Use the filter() method to create a new array


containing only the even numbers
const evens = numbers.filter(function(number) {
return number % 2 === 0;
});

// Print the new array to the console


console.log(evens);

Exercise 5.6: Random Quote Generator


HTML:

Page 196
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Random Quote Generator</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<div class="container">
<h1>Random Quote Generator</h1>
<blockquote>
<p id="quote"></p>
</blockquote>
<button id="btn">Generate</button>
</div>
<script src="script.js"></script>
</body>
</html>

CSS:
.container {
max-width: 800px;
margin: 0 auto;
text-align: center;
}

blockquote {
font-size: 24px;
margin-bottom: 40px;
}

button {
padding: 10px 20px;
font-size: 20px;
border: none;
background-color: #007bff;
color: white;

Page 197
cursor: pointer;
}

JavaScript
const quotes = [
"The best way to predict the future is to invent it.
- Alan Kay",
"The only way to do great work is to love what you
do. - Steve Jobs",
"If you want to achieve greatness, stop asking for
permission. - Unknown",
"It does not matter how slowly you go as long as you
do not stop. - Confucius",
"Success is not final, failure is not fatal: It is
the courage to continue that counts. - Winston
Churchill",
"Believe you can and you're halfway there. - Theodore
Roosevelt",
"Don't watch the clock; do what it does. Keep going.
- Sam Levenson",
"You are never too old to set another goal or to
dream a new dream. - C.S. Lewis",
"If you can dream it, you can do it. - Walt Disney",
"The only person you are destined to become is the
person you decide to be. - Ralph Waldo Emerson"
];

const quoteElem = document.getElementById("quote");


const btn = document.getElementById("btn");

function generateQuote() {
const randomIndex = Math.floor(Math.random() *
quotes.length);
quoteElem.textContent = quotes[randomIndex];
}

btn.addEventListener("click", generateQuote);

Page 198
Exercise 6.1: Creating a Class
// Define a class called Person with properties 'name'
and 'age'
class Person {
constructor(name, age) {
this.name = name;
this.age = age;
}
}

// Create a new Person object and print out their name


and age
const person1 = new Person('Alice', 30);
console.log(`${person1.name} is ${person1.age} years
old.`);

// Create another Person object and print out their


name and age
const person2 = new Person('Bob', 25);
console.log(`${person2.name} is ${person2.age} years
old.`);

Code Exercise 6.2: Creating Subclasses


// Define a class called Animal with properties
'species' and 'sound'
class Animal {
constructor(species, sound) {
this.species = species;
this.sound = sound;
}

makeSound() {
console.log(`${this.species} makes a ${this.sound}
sound.`);

Page 199
}
}

// Define two subclasses of Animal: Dog and Cat


class Dog extends Animal {
constructor(name) {
super('Dog', 'bark');
this.name = name;
}

wagTail() {
console.log(`${this.name} wags its tail.`);
}
}

class Cat extends Animal {


constructor(name) {
super('Cat', 'meow');
this.name = name;
}

purr() {
console.log(`${this.name} purrs.`);
}
}

// Create a new Dog object and call its methods


const dog1 = new Dog('Buddy');
dog1.makeSound();
dog1.wagTail();

// Create a new Cat object and call its methods


const cat1 = new Cat('Fluffy');
cat1.makeSound();
cat1.purr();

Exercise 7.1: Inserting Breakpoints

Page 200
No solution Set

Exercise 7.2: Try/Catch/Finally


function divide(numerator, denominator) {
if (denominator === 0) {
throw new Error("Division by zero");
}
return numerator / denominator;
}

try {
console.log(divide(10, 2));
} catch (error) {
console.log("Error:", error.message);
} finally {
console.log("Function call finished.");
}

try {
console.log(divide(10, 0));
} catch (error) {
console.log("Error:", error.message);
} finally {
console.log("Function call finished.");
}

try {
console.log(divide("abc", 2));
} catch (error) {
console.log("Error:", error.message);
} finally {
console.log("Function call finished.");
}

Exercise 7.3: Throwing Exceptions


No solution Set

Page 201
Exercise 8.1: Accessing and Modifying DOM Elements
HTML
<!DOCTYPE html>
<html>
<head>
<title>Exercise 8.1</title>
</head>
<body>
<h1 id="heading">This is a heading</h1>
<p id="paragraph">This is a paragraph</p>
<button id="button">Click me</button>
<script src="script.js"></script>
</body>
</html>

JavaScript
const heading = document.getElementById('heading');
const paragraph = document.getElementById('paragraph');
const button = document.getElementById('button');

button.addEventListener('click', function() {
heading.textContent = 'New Heading';
paragraph.textContent = 'New Paragraph';
});

Exercise 8.2: Modifying CSS


HTML
<!DOCTYPE html>
<html>
<head>
<title>Exercise 8.2</title>
<style>
body {
background-color: white;
}
</style>

Page 202
</head>
<body>
<button id="button">Click me</button>
<script src="script.js"></script>
</body>
</html>

JavaScript
const button = document.getElementById('button');

button.addEventListener('click', function() {
document.body.style.backgroundColor = 'red';
});

Exercise 8.3: Responding to Mouse Events


HTML

<!DOCTYPE html>
<html>
<head>
<title>Exercise 8.3</title>
</head>
<body>
<button id="button">Mouse Over Me</button>
<script src="script.js"></script>
</body>
</html>

JavaScript
const button = document.getElementById('button');

button.addEventListener('mouseover', function() {
button.textContent = 'Mouse is over me';
});

Page 203
button.addEventListener('mouseout', function() {
button.textContent = 'Mouse over me';
});

Exercise 8.4: Responding to Keyboard Events


HTML
<!DOCTYPE html>
<html>
<head>
<title>Exercise 8.4</title>
</head>
<body>
<input type="text" id="textInput">
<p id="output"></p>
<script src="script.js"></script>
</body>
</html>

JavaScript
const textInput = document.getElementById('textInput');
const output = document.getElementById('output');

textInput.addEventListener('keydown', function(event) {
output.textContent = event.key;
});

Exercise 8.5: Modifying HTML Attributes


HTML
<!DOCTYPE html>
<html>
<head>
<title>Exercise 8.5</title>
</head>

Page 204
<body>
<img id="image"
src="https://www.w3schools.com/html/pic_trulli.jpg">
<button id="button">Change Image</button>
<script src="script.js"></script>
</body>
</html>

JavaScript
const image = document.getElementById('image');
const button = document.getElementById('button');

button.addEventListener('click', function() {
image.setAttribute('src',
'https://www.w3schools.com/html/pic_bulbo.jpg');
});

Exercise 8.6: Creating and Removing Elements


HTML
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Creating and Removing Elements</title>
</head>
<body>
<button id="toggleBtn">Toggle Paragraph</button>
<div id="paragraphContainer"></div>
</body>
</html>

JavaScript
const toggleBtn = document.querySelector('#toggleBtn');
const paragraphContainer =
document.querySelector('#paragraphContainer');

Page 205
let paragraph = null;
let paragraphVisible = false;

toggleBtn.addEventListener('click', () => {
if (!paragraphVisible) {
paragraph = document.createElement('p');
paragraph.textContent = 'This paragraph was created
dynamically!';
paragraphContainer.appendChild(paragraph);
paragraphVisible = true;
} else {
paragraphContainer.removeChild(paragraph);
paragraphVisible = false;
}
});

Exercise 8.7: Event Bubbling and Delegation


HTML
<ul id="myList">
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
</ul>

JavaScript
const list = document.getElementById("myList");

list.addEventListener("click", function(event) {
if (event.target.nodeName === "LI") {
event.target.style.color = "red";
}
});

Exercise 8.8: Interactive Form Validation


HTML

Page 206
<form>
<label for="name">Name:</label>
<input type="text" id="name" name="name"><br><br>

<label for="email">Email:</label>
<input type="email" id="email" name="email"><br><br>

<label for="phone">Phone:</label>
<input type="tel" id="phone" name="phone"><br><br>

<label for="password">Password:</label>
<input type="password" id="password"
name="password"><br><br>

<button id="submitBtn" disabled>Submit</button>


</form>

<div id="message"></div>

JavaScript
// Get form elements
const nameInput = document.getElementById("name");
const emailInput = document.getElementById("email");
const phoneInput = document.getElementById("phone");
const passwordInput =
document.getElementById("password");
const submitBtn = document.getElementById("submit");

// Add event listeners to form inputs


nameInput.addEventListener("blur", validateName);
emailInput.addEventListener("blur", validateEmail);
phoneInput.addEventListener("blur", validatePhone);
passwordInput.addEventListener("blur",
validatePassword);

// Validate name input


function validateName() {

Page 207
const name = nameInput.value.trim();
if (name === "") {
showError(nameInput, "Name is required");
} else if (!isValidName(name)) {
showError(nameInput, "Name can only contain letters
and spaces");
} else {
showSuccess(nameInput);
}
}

// Validate email input


function validateEmail() {
const email = emailInput.value.trim();
if (email === "") {
showError(emailInput, "Email is required");
} else if (!isValidEmail(email)) {
showError(emailInput, "Email is not valid");
} else {
showSuccess(emailInput);
}
}

// Validate phone input


function validatePhone() {
const phone = phoneInput.value.trim();
if (phone === "") {
showError(phoneInput, "Phone number is required");
} else if (!isValidPhone(phone)) {
showError(phoneInput, "Phone number is not valid");
} else {
showSuccess(phoneInput);
}
}

// Validate password input


function validatePassword() {

Page 208
const password = passwordInput.value.trim();
if (password === "") {
showError(passwordInput, "Password is required");
} else if (!isValidPassword(password)) {
showError(
passwordInput,
"Password must be at least 8 characters long and
contain at least one uppercase letter, one lowercase
letter, and one number"
);
} else {
showSuccess(passwordInput);
}
}

// Check if name contains only letters and spaces


function isValidName(name) {
const regex = /^[a-zA-Z\s]+$/;
return regex.test(name);
}

// Check if email is valid


function isValidEmail(email) {
const regex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
return regex.test(email);
}

// Check if phone number is valid


function isValidPhone(phone) {
const regex = /^\d{10}$/;
return regex.test(phone);
}

// Check if password is valid


function isValidPassword(password) {
const regex =
/^(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).{8,}$/;

Page 209
return regex.test(password);
}

// Show error message and add error class


function showError(input, message) {
const formControl = input.parentElement;
formControl.classList.add("error");
const errorMessage =
formControl.querySelector("small");
errorMessage.innerText = message;
}

// Show success message and add success class


function showSuccess(input) {
const formControl = input.parentElement;
formControl.classList.remove("error");
formControl.classList.add("success");
}

// Add event listener to submit button


submitBtn.addEventListener("click", (event) => {
event.preventDefault();
if (validateName() && validateEmail() &&
validatePhone() && validatePassword()) {
alert("Form submitted successfully");
}
});

Exercise 8.9: Click Counter


HTML
<button id="counterBtn">Click me!</button>

Page 210
<div id="counterDisplay">0</div>

JavaScript
const counterBtn =
document.getElementById('counterBtn');
const counterDisplay =
document.getElementById('counterDisplay');
let count = 0;

counterBtn.addEventListener('click', function(event) {
count++;
counterDisplay.innerHTML = count;
});

Exercise 8.10: Image Gallery


HTML
<!DOCTYPE html>
<html>
<head>
<title>Image Gallery</title>
<style>
img {
width: 200px;
height: 200px;
margin: 10px;
}
</style>
</head>
<body>
<img id="img1"
src="https://via.placeholder.com/200x200" alt="Image
1">
<img id="img2"
src="https://via.placeholder.com/200x200" alt="Image
2">
<img id="img3"

Page 211
src="https://via.placeholder.com/200x200" alt="Image
3">
<script src="script.js"></script>
</body>
</html>

JavaScript
const images = document.querySelectorAll("img");

for (let i = 0; i < images.length; i++) {


images[i].addEventListener("click", function(event) {
if (event.shiftKey) {
this.style.width = "200px";
this.style.height = "200px";
} else {
this.style.width = "400px";
this.style.height = "400px";
}
});
}

Exercise 9.1: API Application


HTML
<!DOCTYPE html>
<html>
<head>
<title>Random User API Example</title>
<style>
#user-container {
border: 2px solid #333;
padding: 10px;
margin: 10px;
}
#user-container img {
max-width: 200px;
max-height: 200px;

Page 212
}
</style>
</head>
<body>
<button id="get-user-btn">Get Random User</button>
<div id="user-container"></div>
<script src="script.js"></script>
</body>
</html>

JavaScript
const userContainer =
document.querySelector('#user-container');
const getUserBtn =
document.querySelector('#get-user-btn');

getUserBtn.addEventListener('click', getUser);

function getUser() {
userContainer.innerHTML = ''; // clear previous user
data
userContainer.classList.add('loading'); // add
loading class to div element
fetch('https://randomuser.me/api/')
.then(response => response.json())
.then(data => {
const user = data.results[0];
const userImg = document.createElement('img');
userImg.src = user.picture.large;
userContainer.appendChild(userImg);
const userName = document.createElement('p');
userName.textContent = `${user.name.title}
${user.name.first} ${user.name.last}`;
userContainer.appendChild(userName);
const userLocation = document.createElement('p');
userLocation.textContent =
`${user.location.city}, ${user.location.state},

Page 213
${user.location.country}`;
userContainer.appendChild(userLocation);
userContainer.classList.remove('loading'); //
remove loading class when data is displayed
})
.catch(error => {
console.error('Error:', error);
userContainer.textContent = 'Failed to retrieve
user data. Please try again.';
userContainer.classList.remove('loading'); //
remove loading class when error message is displayed
});
}

CSS
.loading {
background-image: url('loading.gif');
background-size: 50px 50px;
background-repeat: no-repeat;
background-position: center;
}

Page 214
About the Author
Mark Lassoff has taught over 2.5 million people coding and
digital design through online courses, in corporate classrooms
and in technical workshops.

Mark has won multiple awards for his courses and teaching.
Mark’s clients have included Lockheed Martin, Blue Cross/Blue
Shield and Apple. When not teaching, Mark enjoys dining out,
travel, and time with friends and family.

Get in touch with Mark:


Email: mark@frameworktv.com
Web: http://frameworktv.com
Twtitter: http://twitter.com/mlassoff
LinkedIn: http://linkedin.com/in/marklassoff
YouTube: http://youtube.com/@frameworktv

About Framework Tech Media


Framework Tech Media helps people learn career-defining
digital skills like coding, design and digital productivity. Based
in Connecticut, Framework produces online courses, books,
and video programming teaching technical skills. Framework
Tech Media video content appears on YouTube, Roku, and
syndicated channels worldwide.
Get Certified with Mark’s Certified
Web Development Professional
Program
- Earn Recognized Certs while Learning HTML, CSS and JavaScript
- Completely Updated for 2023/2024 with 40 NEW lectures,
coding activities, and projects.

Learn What It Takes to Code Dynamic, Professional Websites


and Web Apps From The Comfort of Your Own Home.

In this comprehensive course, I will show you everything you


need to know so that you can follow in these people’s
footsteps.

You’re going to learn how to code, AND you’re going to


become a certified professional from a recognized
international trainer. And best of all, you’re going to have fun
doing it.

You should complete this course if:

● You’re planning on studying coding at college and


want to build a rock-solid foundation so that you have
a huge head start before your course begins?
● You’re dissatisfied with your current job and want to
learn exactly what it takes to become a fully qualified
web developer
● You’re currently working in IT but want to expand
your skill base so that you’re 100% up to date with the
latest developments in web technology?
● You want to develop mobile apps or websites on the
side to create some additional income while retaining
your current job?

Learn Skills That Will Benefit You for The Rest of Your Life

➔ Imagine being able to create a web app that is


downloaded by millions of paying customers—or a
website that’s visited by people from all seven
continents.
➔ Imagine the limitless opportunities that having these
programming skills will give you.
➔ Imagine working in a field that challenges you and
allows you to express yourself freely every day.
➔ Imagine being paid extremely well for developing
products and services that can help change people’s
lives.
➔ Stop imagining and take action! It’s time to start your
journey. Your future is waiting for you...

Four Certifications in One


The unique Certified Web Development Professional
credential will prove that you have mastered the fundamental
skills new web developers need. You'll have a complete
understanding of HTML5, the language used to structure
websites, and many mobile applications you use daily. From
there, you'll move on to Javascript-- the language of
interaction on the web. The use of Javascript is growing at a
lightning pace, and it's been called "the most important
language to learn today" by multiple experts.

Each language carries its own Specialist Designation for


which you earn a certificate, the privilege of using the
specialist credential badge, and a personal online transcript
page showing your designations, certification, and
accomplishments.

This course is specially designed to prepare you for the Web


Development Professional Certification from Dollar Design
School. This certification will allow you to prove that you
have achieved competencies in HTML, CSS, and JavaScript--
everything you need to create basic web applications.

New for 2023/24


No exams are required to earn your certifications. Complete
and submit all the lab activities for the course program, and
you'll earn your new certifications!
Certified Web Developers will receive the following:
A printable certificate indicating the new certification
that you can present to employers or prospects
A letter explaining the certification and its value to a
prospective employer. The letter will state exactly
what mastery the certification represents.
Authorization to use the Dollar Design School Certified
Web Developer Badge on your website and marketing
materials
Automatic linkage to your LinkedIn account to display
your certification

Testimonials
"This is a great course it's very beginner friendly love the
assignments but to be honest they can feel a bit lengthy
I love the small in between humors from Mark
Thanks for this amazing course looking forward to learning
more from this course " - Nabeel Wasif

“… The videos were very thorough but the best are the exercises
that you must complete. Like Mark says, writing code is not a
spectator sport" - Dan Dlhy

“I took the web development courses from Dollar Design


School. The course is awesome. Every point is being discussed
very carefully. So great study materials.” -Bivas Ganguly

“I am taking Web Development Masterclass & Certifications!


So far I learned html and CSS. Best thing about training is the
organization of the course and how smooth it is. Also the
professor mark Lassoff makes the video very energetic and
exciting to watch. I would recommend this course to anyone
looking into front-end developing.” - Josh Singh

“I just completed the CSS foundations course and this is the


first time I’m able to understand css flex. The best part about
learning with this course is the coding exercise at the end of
each tutorial. It gives me a chance to try out the concepts and
apply the knowledge. The final certification project at the end
of each course is pretty neat too. Thank you so much.” -
Ndidiamaka Ugwu

“​​I started the course because i wanted to learn something new,


something I haven't had any experience with before. So now i'm
considering starting a whole new career…. The concept of the
course is extremely good and everything is explained really
thoroughly– so even i understood it!

The thing that I really liked was Mark's approach to teaching


by implementing subtle humor in the subject. I will definitely
take another course in the near future….” - Igor Kruc

Discount for Readers


As a reader of this book you’re entitled to a 15% discount on
Become a Certified Web Developer Program. Order at
https://learntoprogram.samcart.com/products/certified-web
-foundations-professional-2023/ and usd the coupon code
READER to obtain your discount.

You might also like