0% found this document useful (0 votes)
3 views256 pages

1 Javascript

This document provides an overview of JavaScript fundamentals, including syntax, variables, and data types. It covers key concepts such as whitespace, statements, identifiers, comments, and the differences between declared and undeclared variables. Additionally, it explains primitive data types like null, undefined, boolean, number, string, symbol, and bigint, as well as how to declare and initialize variables.

Uploaded by

ROSHAN URKANDE
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
3 views256 pages

1 Javascript

This document provides an overview of JavaScript fundamentals, including syntax, variables, and data types. It covers key concepts such as whitespace, statements, identifiers, comments, and the differences between declared and undeclared variables. Additionally, it explains primitive data types like null, undefined, boolean, number, string, symbol, and bigint, as well as how to declare and initialize variables.

Uploaded by

ROSHAN URKANDE
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 256

Section 1.

Fundamentals

Syntax
Summary: in this tutorial, you will learn about JavaScript syntax, including whitespace,
statements, identi ers, comments, expressions, and keywords.

Whitespace
Whitespace refers to characters that provide the space between other characters. JavaScript
has the following whitespace:
• Carriage return
• Space
• New Line
• tab
JavaScript engine ignores whitespace. However, you can use whitespace to format the code
to make it easy to read and maintain.
The following JavaScript code doesn’t use whitespace:

let formatted = true; if (formatted) {console.log('The code is easy to read');}

It’s is equivalent to the following code that uses whitespace. Hence, this code is much easy to read:

let formatted = true;

if (formatted) {
console.log('The code is easy to read');
}

Note that JavaScript bundlers remove all whitespace from JavaScript les and put them into
a single le for deployment. By doing this, JavaScript bundlers make the JavaScript code
lighter and faster to load in the web browsers.
fi
fi
fi
Statements
A statement is a code that declares a variable or instructs the JavaScript engine to do a task.
A simple statement is terminated by a semicolon (;).
Although the semicolon (;) is optional; you should always use it to terminate a statement. For
example, the following declares a variable and shows it to the console:

let message = "Welcome to JavaScript";


console.log(message);

Blocks
A block is a sequence of zero or more simple statements. A block is delimited by a pair of
curly brackets {}. For example:

if (window.localStorage) {
console.log('The local storage is supported');
}

Identi ers
An identi er is a name you choose for variables, parameters, functions, classes, etc. An identi er
name starts with a letter (a-z, or A-Z), an underscore(_), or a dollar sign ($) and is followed by a
sequence of characters including (a-z, A-Z), numbers (0-9), underscores (_), and dollar signs ($).

Note that the letter is not limited to the ASCII character and may include extended ASCII or
Unicode though not recommended.

Identi ers are case-sensitive. For example, the message is different from the Message.

Comments
Comments allow you to add notes or hints to JavaScript code. When executing the code, the
JavaScript engine ignores the comments.
JavaScript supports single-line and block comments.

Single-line comments
A single-line comment starts with two forward-slashes characters (//). A single-line comment makes
all the text following the // on the same line into a comment. For example:

// this is a single-line comment


fi
fi
fi
fi
Block comments
A delimited comment begins with a forward slash and asterisk /* and ends with the opposite */ as in
the following example:

/* This is a block comment


that can span multiple lines */

Expressions
An expression is a piece of code that evaluates to a value. For example:

2+1

The above expression returns three.

Keywords & Reserved words


JavaScript de nes a list of reserved keywords that have speci c uses. Therefore, you cannot
use the reserved keywords as identi ers or property names by rules.
The following table shows the JavaScript reserved words de ned in ECMA-262:

break case catch


continue debugger default
else export extends
function if import
new return super
throw try null
void while with
class delete nally
in switch typeof
yield const do
for instanceof this
var
fi
fi
fi
fi
fi
In addition to the reserved keywords, ECMA-252 also de ne a list of future reserved words
that cannot be used as identi ers or property names:

enum implements let


protected private public
await interface package
implements public

Summary
• Use whitespace including cariage return, space, newline, and tab to format the code.
The JavaScript engine ignores the whiespace.
• Use a semicolon (;) to terminate a simple statement.
• Use the curly braces ({}) to form a block that groups one or more simple statments.
• A single-line comment start with // followed by a text. A block comment begins with /
* and ends with */. JavaScript engine also ignores the comments.
• Identifers are names that you choose for variables, functions, classes, etc.
• Do not use the reserved keywords and reserved words for identifers.
fi
fi
Variables
Summary: in this tutorial, you’ll learn about JavaScript variables and how to use variables to
store values in the application.
A variable is a label that references a value like a number or string. Before using a variable,
you need to declare it.

Declare a variable
To declare a variable, you use the var keyword followed by the variable name as follows:

var message;

A variable name can be any valid identi er. By default, the message variable has a special value unde ned if you
have not assigned a value to it.

Variable names follow these rules:

• Variable names are case-sensitive. This means that the message and Message are different variables.
• Variable names can only contain letters, numbers, underscores, or dollar signs and cannot contain spaces.
Also, variable names must begin with a letter, an underscore (_) or a dollar sign ($).
• Variable names cannot use the reserved words.
By convention, variable names use camelcase like message, yourAge, and myName.

JavaScript is a dynamically typed language. This means that you don’t need to specify the variable’s type in the
declaration like other static typed languages such as Java or C#.

Starting in ES6, you can use the let keyword to declare a variable like this:

let message;

It’s a good practice to use the let keyword to declare a variable. Later, you’ll learn the
differences between var and let keywords. And you should not worry about it for now.

Initialize a variable
Once you have declared a variable, you can initialize it with a value. To initialize a variable, you specify the
variable name, followed by an equals sign (=) and a value.

For example, The following declares the message variable and initializes it with a literal string “Hello":

let message;
message = "Hello";
fi
fi
To declare and initialize a variable at the same time, you use the following syntax:

let variableName = value;

For example, the following statement declares the message variable and initializes it with the literal string “Hello":

let message = "Hello";

JavaScript allows you to declare two or more variables using a single statement. To separate
two variable declarations, you use a comma (,) like this:

let message = "Hello",


counter = 100;

Since JavaScript is a dynamically typed language, you can assign a value of a different type
to a variable. Although, it is not recommended. For example:

let message = 'Hello';


message = 100;

Change a variable
Once you initialize a variable, you can change its value by assigning a different value. For example:

let message = "Hello";


message = 'Bye';

Unde ned vs. undeclared variables


It’s important to distinguish between unde ned and undeclared variables.
An unde ned variable is a variable that has been declared but has not been initialized with a
value. For example:

let message;
console.log(message); // unde ned

In this example, the message variable is declared but not initialized. Therefore, the message variable is unde ned.

In contrast, an undeclared variable is a variable that has not been declared. For example:

console.log(counter);
fi
fi
fi
fi
fi
Output:

console.log(counter);
^
ReferenceError: counter is not de ned

In this example, the counter variable has not been declared. Hence, accessing it causes a ReferenceError.

Constants
A constant holds a value that doesn’t change. To declare a constant, you use the const
keyword. When de ning a constant, you need to initialize it with a value. For example:

const workday = 5;

Once de ning a constant, you cannot change its value.

The following example attempts to change the value of the workday constant to 4 and causes an error:

workday = 2;

Error:

Uncaught TypeError: Assignment to constant variable.

Later, you’ll learn that the const keyword actually de nes a read-only reference to a value in
the constants tutorial.

Summary
• A variable is a label that references a value.
• Use the let keyword to declare a variable.
• An unde ned variable is a variable that has been declared but not initialized while an
undeclared variable is variable that has not been declared.
• Use the const keyword to de ne a readonly reference to a value.
fi
fi
fi
fi
fi
fi
Data types
Summary: in this tutorial, you will learn about the JavaScript data types and their unique characteristics.

JavaScript has the primitive data types:

1. null

2. unde ned

3. boolean

4. number

5. string

6. symbol – available from ES2015

7. bigint – available from ES2020

and a complex data type object.


fi
JavaScript is a dynamically typed language. It means that a variable doesn’t associate with a
type. In other words, a variable can hold a value of different types. For example:

let counter = 120; // counter is a number


counter = false; // counter is now a boolean
counter = "foo"; // counter is now a string

To get the current type of the value that the variable stores, you use the typeof operator:

let counter = 120;


console.log(typeof(counter)); // "number"

counter = false;
console.log(typeof(counter)); // "boolean"

counter = "Hi";
console.log(typeof(counter)); // "string"

Output:

"number"
"boolean"
"string"

The unde ned type


The unde ned type is a primitive type that has only one value unde ned. By default, when a variable is
declared but not initialized, it is assigned the value of unde ned.

Consider the following example:

let counter;
console.log(counter); // unde ned
console.log(typeof counter); // unde ned

In this example, the counter is a variable. Since counter hasn’t been initialized, it is assigned the
value unde ned. The type of counter is also unde ned.

It’s important to note that the typeof operator also returns unde ned when you call it on a variable
that hasn’t been declared:

console.log(typeof undeclaredVar); // unde ned


fi
fi
fi
fi
fi
fi
fi
fi
fi
fi
The null type
The null type is the second primitive data type that also has only one value null. For example:

let obj = null;


console.log(typeof obj); // object

The typeof null returns object is a known bug in JavaScript. A proposal to x this was
proposed but rejected. The reason was the that x would break a lot of existing sites.

JavaScript de nes that null is equal to unde ned as follows:

console.log(null == unde ned); // true

The number type


JavaScript uses the number type to represent both integer and oating-point numbers.
The following statement declares a variable and initializes its value with an integer:

let num = 100;

To represent a oating-point number, you include a decimal point followed by at least one
number. For example:

let price= 12.5;


let discount = 0.05;

Note that JavaScript automatically converts a oating-point number into an integer number if
the number appears to be a whole number.
The reason is that Javascript always wants to use less memory since a oating-point value
uses twice as much memory as an integer value. For example:

let price = 200.00; // interpreted as an integer 200

To get the range of the number type, you use Number.MIN_VALUE and Number.MAX_VALUE. For example:

console.log(Number.MAX_VALUE); // 1.7976931348623157e+308
console.log(Number.MIN_VALUE); // 5e-324

Also, you can use In nity and -In nity to represent the in nite number. For example:

console.log(Number.MAX_VALUE + Number.MAX_VALUE); // In nity


console.log(-Number.MAX_VALUE - Number.MAX_VALUE); // -In nity
fi
fl
fi
fi
fi
fi
fl
fi
fi
fi
fi
fl
fl
fi
NaN
NaN stands for Not a Number. It is a special numeric value that indicates an invalid number. For
example, the division of a string by a number returns NaN:.

console.log('a'/2); // NaN;

The NaN has two special characteristics:

• Any operation with NaN returns NaN.


• The NaN does not equal any value, including itself.
Here are some examples:

console.log(NaN/2); // NaN
console.log(NaN == NaN); // false

The string type


In JavaScript, a string is a sequence of zero or more characters. A string literal begins and
ends with either a single quote(') or a double quote (").
A string that begins with a double quote must end with a double quote. Likewise, a string that
begins with a single quote must also end with a single quote:

let greeting = 'Hi';


let message = "Bye";

If you want to single quote or double quotes in a literal string, you need to use the backslash
to escape it. For example:

let message = 'I\'m also a valid string'; // use \ to escape the single quote (')

JavaScript strings are immutable. This means that it cannot be modi ed once created.
However, you can create a new string from an existing string. For example:

let str = 'JavaScript';


str = str + ' String';
fi
In this example:

• First, declare the str variable and initialize it to a string of 'JavaScript'.


• Second, use the + operator to combine 'JavaScript' with ' String' to make its value as 'Javascript String'.
Behind the scene, the JavaScript engine creates a new string that holds the new string 'JavaScript String' and
destroys the original strings 'JavaScript' and ' String'.

The following example attempts to change the rst character of the string JavaScript:

let s = 'JavaScript';
s[0] = 'j';
console.log(s)

The output is:

'JavaScript'

But not:

'javaScript'

The boolean type


The boolean type has two literal values: true and false in lowercase. The following example declares two
variables that hold the boolean values.

let inProgress = true;


let completed = false;

console.log(typeof completed); // boolean

JavaScript allows values of other types to be converted into boolean values of true or false.
To convert a value of another data type into a boolean value, you use the Boolean() function.
The following table shows the conversion rules:

Type TRUE FALSE


string non-empty string empty string
number non-zero number and In nity 0, NaN
object non-null object null
unde ned unde ned
fi
fi
fi
fi
For example:

console.log(Boolean('Hi'));// true
console.log(Boolean('')); // false

console.log(Boolean(20)); // true
console.log(Boolean(In nity)); // true
console.log(Boolean(0)); // false

console.log(Boolean({foo: 100})); // true on non-empty object


console.log(Boolean(null));// false

The symbol type


JavaScript added a primitive type in ES6: the symbol. Different from other primitive types, the symbol type
does not have a literal form.

To create a symbol, you call the Symbol function as follows:

let s1 = Symbol();

The Symbol function creates a new unique value every time you call it.

console.log(Symbol() == Symbol()); // false

Note that you’ll learn more about symbols in the symbol tutorial.

The bigint type


The bigint type represents the whole numbers that are larger than 253 – 1. To form a bigint literal
number, you append the letter n at the end of the number:

let pageView = 9007199254740991n;


console.log(typeof(pageView)); // 'bigint'

And you’ll learn more about the bigint type here.


fi
The object type
In JavaScript, an object is a collection of properties, where each property is de ned as a key-value pair.

The following example de nes an empty object using the object literal syntax:

let emptyObject = {};

The following example de nes the person object with two properties: rstName and lastName.

let person = {
rstName: 'John',
lastName: 'Doe'
};

A property name of an object can be any string. You can use quotes around the property name if it is not a valid identi er.

For example, if the person object has a property rst-name, you must place it in the quotes such as " rst-name".

A property of an object can hold an object. For example:

let contact = {
rstName: 'John',
lastName: 'Doe',
email: '[email protected]',
phone: '(408)-555-9999',
address: {
building: '4000',
street: 'North 1st street',
city: 'San Jose',
state: 'CA',
country: 'USA'
}
}

The contact object has the rstName, lastName, email, phone, and address properties.

The address property itself holds an object that has building, street, city, state, and country properties.

To access a object’s property, you can use

• The dot notation (.)


• The array-like notation ([]).
The following example uses the dot notation (.) to access the rstName and lastName properties of
the contact object.

console.log(contact. rstName);
console.log(contact.lastName);
fi
fi
fi
fi
fi
fi
fi
fi
fi
fi
fi
fi
If you reference a property that does not exist, you’ll get an unde ned value. For example:

console.log(contact.age); // unde ned

The following example uses the array-like notation to access the email and phone properties of the contact object.

console.log(contact['phone']); // '(408)-555-9999'
console.log(contact['email']); // '[email protected]'

Summary
• JavaScript has the primitive types: number, string, boolean, null, unde ned, symbol and bigint and a
complex type: object.
fi
fi
fi
Number
Summary: in this tutorial, you’ll learn about the JavaScript number types and how to use
them effectively.

Introduction to the JavaScript Number


JavaScript uses the number type to represent both integers and oating-point values. Technically, the
JavaScript number type uses the IEEE-754 format.

ES2020 introduced a new primitive type bigint representing big integer numbers with values larger than 253 – 1.

To support various types of numbers, JavaScript uses different number literal formats.

Integer numbers
The following shows how to declare a variable that holds a decimal integer:

let counter = 100;

Integers can be represented in the following formats:


• Octal (base 8)
• Hexadecimal (based 16)
When you use the octal and hexadecimal numbers in arithmetic operations, JavaScript treats
them as decimal numbers.

Octal numbers
An octal literal number starts with the digit zero (0) followed by a sequence of octal digits
(numbers from 0 through 7). For example:

let num = 071;


console.log(num);

Output:

57

If an octal number contains a number not in the range from 0 to 7, the JavaScript engine
ignores the 0 and treats the number as a decimal. For example:

let num = 080;


console.log(num);
fl
Output:

80

This implicit behavior might cause issues. Therefore, ES6 introduced a new octal literal that
starts with the 0o followed by a sequence of octal digits (from 0 to 7). For example:

let num = 0o71;


console.log(num);

Output:

57

If you an invalid number after 0o, JavaScript will issue a syntax error like this:

let num = 0o80;


console.log(num);

Output:

let num = 0o80;


^^
SyntaxError: Invalid or unexpected token

Hexadecimal numbers
Hexadecimal numbers start with 0x or 0X followed by any number of hexadecimal digits (0
through 9, and a through f). For example:

let num = 0x1a;


console.log(num);

Output:

26
Floating-point numbers
To de ne a oating-point literal number, you include a decimal point and at least one number
after that. For example:

let price = 9.99;


let tax = 0.08;
let discount = .05; // valid but not recommeded

When you have a very big number, you can use e-notation. E-notation indicates a number
should be multiplied by 10 raised to a given power. For example:

let amount = 3.14e7;


console.log(amount);

Output:

31400000

The notation 3.14e7 means that take 3.14 and multiply it by 107.
Likewise, you can use the E-notation to represent a very small number. For example:

let amount = 5e-7;


console.log(amount);

Output:

0.0000005

The 5e-7 notation means that take 5 and divide it by 10,000,000.


Also, JavaScript automatically converts any oating-point number with at least six zeros after
the decimal point into e-notation. For example:

let amount = 0.0000005;


console.log(amount);

Output:

5e-7
fi
fl
fl
Floating-point numbers are accurate up to 17 decimal places. When you perform arithmetic
operations on oating-point numbers, you often get the approximate result. For example:

let amount = 0.2 + 0.1;


console.log(amount);

Output:

0.30000000000000004

Big Integers
JavaScript introduced the bigint type starting in ES2022. The bigint type stores whole numbers whose
values are greater than 253 – 1.

A big integer literal has the n character at the end of an integer literal like this:

let pageView = 9007199254740991n;

Summary
• JavaScript Number type represents both integer and oating-point numbers.
fl
fl
Boolean
Summary: in this tutorial, you’ll learn about the JavaScript boolean type that has two literal values true and false.

Introduction to the JavaScript boolean type


The JavaScript boolean primitive type has two literal values: true and false.

The following example declares two variables and initializes their values to true and false:

let completed = true;


let running = false;

The boolean’s literal values are case-sensitive. This means that the True and False are valid identi ers but
they’re not boolean values.

JavaScript allows the values of other types to be cast to boolean values. To cast a non-Boolean value to a
boolean value, you use the built-in Boolean() function. For example:

let error = 'An error occurred';


let hasError = Boolean(error);

console.log(hasError);

Output:

true

How it works.

• First, declare a variable error that holds a literal string 'An error occurred'.
• Second, cast the error variable to a boolean value using the Boolean() function.
• Third, output the value of the hasError variable to the console.
Because the error variable holds a non-empty string, the Boolean() function casts its value to true.

The following table shows how the Boolean() function casts the values of other types to boolean values:

Data Type Values converted to true Value Converted to false

string Any non-empty string “” (empty string)


number Any Non-zero number 0, NaN
object Any object null
unde ned (not relevant) unde ned
fi
fi
fi
This table is important because some statements automatically cast a non-boolean value to a boolean
value using the Boolean() function.

For example, the if statement executes a block if a condition is true. If you use a non-boolean value, it’ll
use the Boolean() function to implicitly cast that value to a boolean value.

Note that you’ll learn about the if statement in the if tutorial.

See the following example:

let error = 'An error occurred';

if (error) {
console.log(error);
}

Output:

An error occurred

In this example, since the error variable holds a non-empty string, the if statement evaluates its value
to true. Therefore, it executes the console.log(error) to output the error to the console.

If you change the value of the error variable to an empty string (""), you won’t see anything in the output
because the if statement evaluates it as false:

let error = '';


if (error) {
console.log(error);
}

Summary
• JavaScript boolean type has two literal values true and false.
• Use the Boolean() function to cast a non-boolean values to a boolean value.
• Some statements implicitly cast a non-boolean value into a boolean value.
String
Summary: in this tutorial, you’ll learn about the JavaScript string primitive type and how to
use it to de ne strings.

Introduction to the JavaScript strings


JavaScript strings are primitive values. Also, strings are immutable. It means that if you modify a
string, you will always get a new string. The original string doesn’t change.

To create literal strings, you use either single quotes (') or double quotes (") like this:

let str = 'Hi';


let greeting = "Hello";

ES6 introduced template literals that allow you to de ne a string backtick (`) characters:

let name = `John`';

The template literals allow you to use the single quotes and double quotes inside a string without
the need of escaping them. For example:

let mesage = `"I'm good". She said";

Also, you can place the variables and expressions inside a template literal. JavaScript will replace
the variables with their value in the string. This is called string interpolation. For example:

let name = 'John';


let message = `Hi, I'm ${name}.`;

console.log(message);

Output:

Hi, I'm John.

In this example, JavaScript replaces the name variable with its value inside the template literal.
fi
fi
Escaping special characters
To escape special characters, you use the backslash \ character. For example:

• Windows line break: '\r\n'


• Unix line break: '\n'
• Tab: '\t'
• Backslash '\'
The following example uses the backslash character to escape the single quote character in a string:

let str = 'I\'m a string!';

Getting the length of the string


The length property returns the length of a string:

let str = "Good Morning!";


console.log(str.length); // 13

Note that JavaScript has the String type (with the letter S in uppercase), which is
the primitive wrapper type of the primitive string type. Therefore, you can access all
properties and methods of the String type from a primitive string.

Accessing characters
To access the characters in a string, you use the array-like [] notation with the zero-based index.
The following example returns the rst character of a string with the index zero:

let str = "Hello";


console.log(str[0]); // "H"

To access the last character of the string, you use the length - 1 index:

let str = "Hello";


console.log(str[str.length -1]); // "o"
fi
Concatenating strings via + operator
To concatenate two or more strings, you use the + operator:

let name = 'John';


let str = 'Hello ' + name;

console.log(str); // "Hello John"

If you want to assemble a string piece by piece, you can use the += operator:

let className = 'btn';


className += ' btn-primary'
className += ' none';

console.log(className);

Output:

btn btn-primary none

Converting values to string


To convert a non-string value to a string, you use one of the following:

• String(n);
• ”+n
• n.toString()
Note that the toString() method doesn’t work for unde ned and null.

When you convert a string to a boolean, you cannot convert it back. For example:

let status = false;


let str = status.toString(); // "false"
let back = Boolean(str); // true

In this example:
• First, declare the status variable and initialize its with the value of false.
• Second, convert the status variable to a string using the toString() method.
• Third, convert the string back to a boolean value using the Boolean() function. The Boolean() function
converts the string "false" to a boolean value. The result is true because "false" is a non-empty string.

Note that only string for which the Boolean() returns false, is the empty string ('');
fi
Comparing strings
To compare two strings, you use comparison operators such as >, >=, <, <=, and == operators.

The comparison operators compare strings based on the numeric values of the characters. And it
may return the string order that is different from the one used in dictionaries. For example:

let result = 'a' < 'b';


console.log(result); // true

However:

let result = 'a' < 'B';


console.log(result); // false

Summary
• JavaScript strings are primitive values and immutable.
• Literal strings are delimited by single quotes ('), double quotes ("), or backticks (`).
• The length property returns the length of the string.
• Use the comparison operators `>, >=, <, <=, == to compare strings.
Object
Summary: in this tutorial, you will learn about JavaScript objects and how to manipulate
object properties effectively.

Introduction to the JavaScript objects


In JavaScript, an object is an unordered collection of key-value pairs. Each key-value pair is called a property.

The key of a property can be a string. And the value of a property can be any value, e.g., a string, a number,
an array, and even a function.

JavaScript provides you with many ways to create an object. The most commonly used one is to use the object
literal notation.

The following example creates an empty object using the object literal notation:

let empty = {};

To create an object with properties, you use the key:value within the curly braces. For example, the
following creates a new person object:

let person = {
rstName: 'John',
lastName: 'Doe'
};

The person object has two properties rstName and lastName with the corresponding values 'John' and 'Doe'.

When an object has multiple properties, you use a comma (,) to separate them like the above example.

Accessing properties
To access a property of an object, you use one of two notations: the dot notation and array-like notation.

1) The dot notation (.)


The following illustrates how to use the dot notation to access a property of an object:

objectName.propertyName

For example, to access the rstName property of the person object, you use the following expression:

person. rstName
fi
fi
fi
fi
This example creates a person object and shows the rst name and last name to the console:

let person = {
rstName: 'John',
lastName: 'Doe'
};

console.log(person. rstName);
console.log(person.lastName);

2) Array-like notation ( [])


The following illustrates how to access the value of an object’s property via the array-like notation:

objectName['propertyName']

For example:

let person = {
rstName: 'John',
lastName: 'Doe'
};

console.log(person[' rstName']);
console.log(person['lastName']);

When a property name contains spaces, you need to place it inside quotes. For example, the
following address object has the 'building no' as a property:

let address = {
'building no': 3960,
street: 'North 1st street',
state: 'CA',
country: 'USA'
};

To access the 'building no' property, you need to use the array-like notation:

address['building no'];
fi
fi
fi
fi
fi
If you use the dot notation, you’ll get an error:

address.'building no';

Error:

SyntaxError: Unexpected string

Note that it is not a good practice to use spaces in the property names of an object.

Reading from a property that does not exist will result in an unde ned. For example:

console.log(address.district);

Output:

unde ned

Modifying the value of a property


To change the value of a property, you use the assignment operator (=). For example:

let person = {
rstName: 'John',
lastName: 'Doe'
};
person. rstName = 'Jane';
console.log(person);

Output:

{ rstName: 'Jane', lastName: 'Doe' }

In this example, we changed the value of the rstName property of the person object from 'John' to ‘Jane'.

Adding a new property to an object


Unlike objects in other programming languages such as Java and C#, you can add a property to an
object after object creation.
The following statement adds the age property to the person object and assigns 25 to it:

person.age = 25;
fi
fi
fi
fi
fi
fi
Deleting a property of an object
To delete a property of an object, you use the delete operator:

delete objectName.propertyName;

The following example removes the age property from the person object:

delete person.age;

If you attempt to reaccess the age property, you’ll get an unde ned value.

Checking if a property exists


To check if a property exists in an object, you use the in operator:

propertyName in objectName

The in operator returns true if the propertyName exists in the objectName.


The following example creates an employee object and uses the in operator to check if
the ssn and employeeId properties exist in the object:

let employee = {
rstName: 'Peter',
lastName: 'Doe',
employeeId: 1
};

console.log('ssn' in employee);
console.log('employeeId' in employee);

Output:

false
true

Summary
• An object is a collection of key-value pairs.
• Use the dot notation ( .) or array-like notation ([]) to access a property of an object.
• The delete operator removes a property from an object.
• The in operator check if a property exists in an object.
fi
fi
Primitive vs. reference values
Summary: in this tutorial, you’ll learn about two different types of values in JavaScript including
primitive and reference values.

JavaScript has two different types of values:

• Primitive values
• Reference values
Primitive values are atomic pieces of data while reference values are objects that might consist of
multiple values.

Stack and heap memory


When you declare variables, the JavaScript engine allocates the memory for them on two memory locations: stack
and heap.

Static data is the data whose size is xed at compile time. Static data includes:

• Primitive values (null, unde ned, boolean, number, string, symbol, and BigInt)
• Reference values that refer to objects.
Because static data has a size that does not change, the JavaScript engine allocates a xed amount of memory
space to the static data and store it on the stack.

For example, the following declares two variables and initializes their values to a literal string and a number:

let name = 'John';


let age = 25;

Because name and age are primitive values, the JavaScript engine stores these variables on the stack as
shown in the following picture:

Note that strings are objects in many programming languages, including Java and C#.
However, strings are primitive values in JavaScript.
fi
fi
fi
Unlike the stack, JavaScript stores objects (and functions) on the heap. The JavaScript engine doesn’t
allocate a xed amount of memory for these objects. Instead, it’ll allocate more space as needed.

The following example de nes the name, age, and person variables:

let name = 'John';


let age = 25;

let person = {
name: 'John',
age: 25,
};

Internally, the JavaScript engine allocates the memory as shown in the following picture:

In this picture, JavaScript allocates memory on the stack for the three variables name, age, and person.

The JavaScript engine creates a new object on the heap memory. Also, it links the person variable on the
stack memory to the object on the heap memory.

Because of this, we say that the person variable is a reference that refers to an object.
fi
fi
Dynamic properties
A reference value allows you to add, change, or delete properties at any time. For example:

let person = {
name: 'John',
age: 25,
};

// add the ssn property


person.ssn = '123-45-6789';

// change the name


person.name = 'John Doe';

// delete the age property


delete person.age;

console.log(person);

Output:

{ name: 'John Doe', ssn: '123-45-6789' }

Unlike a reference value, a primitive value cannot have properties. This means that you cannot add a property to a
primitive value.

JavaScript allows you to add a property to a primitive value. However, it won’t take any effect. For example:

let name = 'John';


name.alias = 'Knight';

console.log(name.alias); // unde ned

Output:

unde ned

In this example, we add the alias property to the name primitive value. But when we access the alias property via
the name primitive value, it returns unde ned.
fi
fi
fi
Copying values
When you assign a primitive value from one variable to another, the JavaScript engine creates a
copy of that value and assigns it to the variable. For example:

let age = 25;


let newAge = age;

In this example:

• First, declare a new variable age and initialize its value with 25.
• Second, declare another variable newAge and assign the age to the newAge variable.
Behind the scene, the JavaScript engine creates a copy of the primitive value 25 and assign it to the newAge variable.

The following picture illustrates the stack memory after the assignment:

On the stack memory, the newAge and age are separate variables. If you change the value of one
variable, it won’t affect the other.

For example:

let age = 25;


let newAge = age;

newAge = newAge + 1;
console.log(age, newAge);
When you assign a reference value from one variable to another, the JavaScript engine creates a
reference so that both variables refer to the same object on the heap memory. This means that if
you change one variable, it’ll affect the other.

For example:

let person = {
name: 'John',
age: 25,
};

let member = person;

member.age = 26;

console.log(person);
console.log(member);

How it works.

First, declare a person variable and initialize its value with an object with two properties name and age.

Second, assign the person variable to the member variable. In the memory, both variables reference the
same object, as shown in the following picture:

Third, change the age property of the object via the member variable:

Since both person and member variables reference the same object, changing the object via the member variable is
also re ected in the person variable.
fl
Summary
• Javascript has two types of values: primitive values and reference values.
• You can add, change, or delete properties to a reference value, whereas you cannot do
it with a primitive value.
• Copying a primitive value from one variable to another creates a separate value copy. It
means that changing the value in one variable does not affect the other.
• Copying a reference from one variable to another creates a reference so that two
variables refer to the same object. This means that changing the object via one variable
re ects in another variable.
fl
Array
Summary: in this tutorial, you’ll learn about JavaScript arrays and their basic operations.

Introduction to JavaScript arrays


In JavaScript, an array is an ordered list of values. Each value is called an element speci ed by an index:

A JavaScript array has the following characteristics:

1. First, an array can hold values of mixed types. For example, you can have an array that
stores elements with the types number, string, boolean, and null.

2. Second, the size of an array is dynamic and auto-growing. In other words, you don’t need to
specify the array size up front.

Creating JavaScript arrays


JavaScript provides you with two ways to create an array. The rst one is to use the Array constructor as follows:

let scores = new Array();

The scores array is empty, which does hold any elements.

If you know the number of elements that the array will hold, you can create an array with an initial size as
shown in the following example:

let scores = Array(10);

To create an array and initialize it with some elements, you pass the elements as a comma-separated list
into the Array() constructor.

For example, the following creates the scores array that has ve elements (or numbers):

let scores = new Array(9,10,8,7,6);


fi
fi
fi
Note that if you use the Array() constructor to create an array and pass a number into it,
you are creating an array with an initial size.

However, when you pass a value of another type like string into the Array() constructor, you create
an array with an element of that value. For example:

let athletes = new Array(3); // creates an array with initial size 3


let scores = new Array(1, 2, 3); // create an array with three numbers 1,2 3
let signs = new Array('Red'); // creates an array with one element 'Red'

JavaScript allows you to omit the new operator when you use the Array() constructor. For example,
the following statement creates the artists array.

let artists = Array();

In practice, you’ll rarely use the Array() constructor to create an array.

The more preferred way to create an array is to use the array literal notation:

let arrayName = [element1, element2, element3, ...];

The array literal form uses the square brackets [] to wrap a comma-separated list of elements.

The following example creates the colors array that holds string elements:

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

To create an empty array, you use square brackets without specifying any element like this:

let emptyArray = [];

Accessing JavaScript array elements


JavaScript arrays are zero-based indexed. In other words, the rst element of an array starts
at index 0, the second element starts at index 1, and so on.
To access an element in an array, you specify an index in the square brackets []:

arrayName[index]
fi
The following shows how to access the elements of the mountains array:

let mountains = ['Everest', 'Fuji', 'Nanga Parbat'];

console.log(mountains[0]); // 'Everest'
console.log(mountains[1]); // 'Fuji'
console.log(mountains[2]); // 'Nanga Parbat'

To change the value of an element, you assign that value to the element like this:

let mountains = ['Everest', 'Fuji', 'Nanga Parbat'];


mountains[2] = 'K2';

console.log(mountains);

Output:

[ 'Everest', 'Fuji', 'K2' ]

Getting the array size


Typically, the length property of an array returns the number of elements. The following example
shows how to use the length property:

let mountains = ['Everest', 'Fuji', 'Nanga Parbat'];


console.log(mountains.length); // 3

Summary
• In JavaScript, an array is an order list of values. Each value is called an element speci ed by an index.
• An array can hold values of mixed types.
• JavaScript arrays are dynamic, which means that they grow or shrink as needed.
fi
Section 2. Operators

Arithmetic operators
Summary: in this tutorial, you will learn how to use JavaScript arithmetic operators to perform
arithmetic calculations.

Introduction to the JavaScript Arithmetic Operators


JavaScript supports the following standard arithmetic operators:

Operator Sign
Addition +
Subtraction -
Multiplication *
Division /

An arithmetic operator accepts numerical values as operands and returns a single numerical value.
The numerical values can be literals or variables.

Addition operator (+)


The addition operator returns the sum of two values. For example, the following uses the addition
operator to calculate the sum of two numbers:

let sum = 10 + 20;


console.log(sum); // 30

Also, you can use the addition operator with two variables. For example:

let netPrice = 9.99,


shippingFee = 1.99;
let grossPrice = netPrice + shippingFee;
console.log(grossPrice);

Output:

11.98
If either value is a string, the addition operator uses the following rules:
• If both values are strings, it concatenates the second string to the rst one.
• If one value is a string, it implicitly converts the numeric value into a string and
concatenates two strings.
For example, the following uses the addition operator to add concatenate two strings:

let x = '10',
y = '20';
let result = x + y;

console.log(result);

Output:

1020

The following example shows how to use the addition operator to calculate the sum of a
number and a string:

let result = 10 + '20';


console.log(result);

Output:

1020

In this example, JavaScript converts the number 10 into a string '10' and concatenates the second string '20' to it.

The following table shows the result when using the addition operator with special numbers:

Explanation
If either value is NaN, the result is NaN
In nity + In nity = In nity
-In nity + ( -In nity) = – In nity
In nity + -In nity = NaN
+0 + (+0) = +0
-0 + (+0) = +0
-0 + (-0) = -0
fi
fi
fi
fi
fi
fi
fi
fi
fi
Subtraction operator (-)
The subtraction operator (-) subtracts one number from another. For example:

let result = 30 - 10;


console.log(result); // 20

If a value is a string, a boolean, null, or unde ned, the JavaScript engine will:
• First, convert the value to a number using the Number() function.
• Second, perform the subtraction.
The following table shows how to use the subtraction operator with special values:

Explanation
If either value is NaN, the result is NaN
In nity – In nity = NaN
-In nity – ( -In nity) = NaN
In nity
+0 – (+0) = 0
+0 – (-0) = 0
-0 – (-0) = 0

Multiplication operator (*)


JavaScript uses the asterisk (*) to represent the multiplication operator. The multiplication operator
multiplies two numbers and returns a single value. For example:

let result = 2 * 3;
console.log(result);

Output:

If either value is not a number, the JavaScript engine implicitly converts it into a number using
the Number() function and performs the multiplication. For example:

let result = '5' * 2;

console.log(result);
fi
fi
fi
fi
fi
fi
Output:

10

The following table shows how the multiply operator behaves with special values:
Explanation
If either value is NaN, the result is NaN
In nity * 0 = NaN
-In nity * 100 = -In nity
In nity * (-100) = -In nity
In nity * In nity = In nity

Divide operator (/)


Javascript uses the slash (/) character to represent the divide operator. The divide operator divides
the rst value by the second one. For example:

let result = 20 / 10;


console.log(result); // 2

If either value is not a number, the JavaScript engine converts it into a number for division. For example:

let result = '20' / 2;


console.log(result); // 10;

The following table shows the divide operators’ behavior when applying to special values:

Explanation
If either value is NaN, the result is NaN
1/0 = In nity
In nity / In nity = NaN
0/0 = NaN
In nity / 2 = In nity
In nity / -2 = -In nity
fi
fi
fi
fi
fi
fi
fi
fi
fi
fi
fi
fi
fi
fi
fi
fi
Using JavaScript arithmetic operators with objects
If a value is an object, the JavaScript engine will call the valueOf() method of the object to get the
value for calculation. For example:

let energy = {
valueOf() {
return 100;
},
};

let currentEnergy = energy - 10;


console.log(currentEnergy);

currentEnergy = energy + 100;


console.log(currentEnergy);

currentEnergy = energy / 2;
console.log(currentEnergy);

currentEnergy = energy * 1.5;


console.log(currentEnergy);

Output:

90
200
50
150

If the object doesn’t have the valueOf() method but has the toString() method, the JavaScript engine
will call the toString() method to get the value for calculation. For example:

let energy = {
toString() {
return 50;
},
};
let currentEnergy = energy - 10;
console.log(currentEnergy);
currentEnergy = energy + 100;
console.log(currentEnergy);
currentEnergy = energy / 2;
console.log(currentEnergy);
currentEnergy = energy * 1.5;
console.log(currentEnergy);
Output:

40
150
25
75

Summary
• Use the JavaScript arithmetic operators including addition (+), subtraction (-), multiply (*) and
divide (/) to perform arithmetic operations.
Remainder operator
Summary: in this tutorial, you’ll learn about the JavaScript remainder operator (%) to get the
remainder of a number divided by another number.

Introduction to the JavaScript remainder operator


JavaScript uses the % to represent the remainder operator. The remainder operator returns
the remainder left over when one value is divided by another value.
Here’s the syntax of the remainder operator:

dividend % divisor

The following shows the equation for the remainder:

dividend = divisor * quotient + remainder


where |remainder| < |divisor|

In this equation, the dividend, divisor, quotient, and remainder are all integers. The sign of the remainder is
the same as the sign of the dividend.

The sign of the remainder is the same as the sign of the dividend.

JavaScript remainder operator examples


Let’s take some examples of using the JavaScript remainder operator.

1) Using the remainder operator with positive dividend example


The following example shows how to use the remainder operator with a positive dividend:

let remainder = 5 % -2;


console.log(remainder); // 1

remainder = 5 % 2;
console.log(remainder); // 1
2) Using the remainder operator with negative dividend example
The following example uses the remainder operator with a negative dividend:

let remainder = -5 % 3;
console.log(remainder); // -2

remainder = -5 % -3;
console.log(remainder); // -2

3) Using the remainder operator special values


If a dividend is an In nity and a divisor is a nite number, the remainder is NaN. For example:

let remainder = In nity % 2;


console.log(remainder); // NaN

If a dividend is a nite number and a divisor is zero, the remainder is NaN:

let remainder = 10 % 0;
console.log(remainder); // NaN

If both dividend and divisor are In nity, the remainder is NaN:

let remainder = In nity % In nity;


console.log(remainder); // NaN

If a dividend is a nite number and the divisor is an In nity, the remainder is the dividend. For example:

let remainder = 10 % In nity;


console.log(remainder); // 10

If the dividend is zero and the divisor is non-zero, the remainder is zero:

let remainder = 0 % 10;


console.log(remainder); // 0

If either dividend or divisor is not a number, it’s converted to a number using the Number() function
and applied the above rules. For example:

let remainder = '10' % 3;


console.log(remainder); // 1
fi
fi
fi
fi
fi
fi
fi
fi
fi
fi
Using the remainder operator to check if a number is an odd number
To check if a number is an odd number, you use the remainder operator (%) like the following example:

let num = 13;


let isOdd = num % 2;

In this example, if the num is an odd number, the remainder is one. But if the num is an even number, the
remainder is zero.

Later, you’ll learn how to de ne a function that returns true if a number is odd or false otherwise like this:

function isOdd(num) {
return num % 2;
}

Or using an arrow function in ES6:

const isOdd = (num) => num % 2;

Remainder vs Modulo operator


In JavaScript, the remainder operator (%) is not the modulo operator.

If you have been working with Python, you may nd the % represents the modulo operator in this
language. However, it is not the case in JavaScript.

To get a modulo in JavaScript, you use the following expression:

((dividend % divisor) + divisor) % divisor

Or wrap it in a function:

const mod = (dividend, divisor) => ((dividend % divisor) + divisor) % divisor;

If the division and divisor have the same sign, the remainder and modulo operators return the
same result. Otherwise, they return different results.
fi
fi
For example:

const mod = (dividend, divisor) => ((dividend % divisor) + divisor) % divisor;

// dividen and divisor have the same sign


console.log('remainder:', 5 % 3); // 2
console.log('modulo:', mod(5, 3)); // 2

// dividen and divisor have the di erent signs


console.log('remainder:', -5 % 3); // -2
console.log('modulo:', mod(-5, 3)); // 1

Output:

remainder: 2
modulo: 2
remainder: -2
modulo: 1

Summary
• Use the JavaScript remainder operator (%) get the the remainder of a value divided by
another value.
ff
Assignment operators
Summary: in this tutorial, you will learn how to use JavaScript assignment operators to
assign a value to a variable.

Introduction to JavaScript assignment operators


An assignment operator (=) assigns a value to a variable. The syntax of the assignment operator is as follows:

let a = b;

In this syntax, JavaScript evaluates the expression b rst and assigns the result to the variable a.

The following example declares the counter variable and initializes its value to zero:

let counter = 0;

The following example increases the counter variable by one and assigns the result to the counter variable:

let counter = 0;
counter = counter + 1;

When evaluating the second statement, JavaScript evaluates the expression on the right hand rst (counter + 1)
and assigns the result to the counter variable. After the second assignment, the counter variable is 1.

To make the code more concise, you can use the += operator like this:

let counter = 0;
counter += 1;

In this syntax, you don’t have to repeat the counter variable twice in the assignment.

The following table illustrates assignment operators that are shorthand for another operator and the assignment:
fi
fi
Operator Meaning Description
a = b a = b Assigns the value of b to a.
a += b a = a + b Assigns the result of a plus b to a.
a -= b a = a - b Assigns the result of a minus b to a.
a *= b a = a * b Assigns the result of a times b to a.

a /= b a = a / b Assigns the result of a divided by b to a.


a %= b a = a % b Assigns the result of a modulo b to a.
a &=b a = a & b Assigns the result of a AND b to a.
a |=b a = a | b Assigns the result of a OR b to a.
a ^=b a = a ^ b Assigns the result of a XOR b to a.
a <<= b a = a << b Assigns the result of a shifted left by b to a.
a >>= b a = a >> b Assigns the result of a shifted right (sign preserved) by b to a.

a >>>= b a = a >>> b Assigns the result of a shifted right by b to a.

Chaining JavaScript assignment operators


If you want to assign a single value to multiple variables, you can chain the assignment
operators. For example:

let a = 10, b = 20, c = 30;


a = b = c; // all variables are 30

In this example, JavaScript evaluates from right to left. Therefore, it does the following:

let a = 10, b = 20, c = 30;

b = c; // b is 30
a = b; // a is also 30

Summary
• Use the assignment operator (=) to assign a value to a variable.
• Chain the assignment operators if you want to assign a single value to multiple variables.
Unary operators
Summary: in this tutorial, you will learn how to use JavaScript unary operators that take a
single operand and performs an operation.

Introduction to the JavaScript unary operators


Unary operators work on one value. The following table shows the unary operators and their meanings:

Unary Operators Name Meaning


+x
Unary Plus Convert a value into a number
Unary Minus
-x Convert a value into a number and
negate it
++x Increment Operator (Pre x) Add one to the value
–x Decrement Operator (Pre x) Subtract one from the value
x++ Increment Operator (Post x) Add one to the value
x– Decrement Operator (Post x) Subtract one from the value

Unary plus (+)


The unary plus operator is a simple plus sign (+). If you place the unary plus before a numeric value, it
does nothing. For example

let x = 10;
let y = +x;

console.log(y); // 10

When you apply the unary plus operator to a non-numeric value, it performs a number conversion
using the Number() function wit the rules in the following table:
Value Result
boolean false to 0, true to 1
string Convert the string value based on a set of speci c rules
object Call the valueOf() and/or toString() method to get the value to convert into a
number

For example, the following uses the unary plus operator to convert the string '10' to the number 10:

let s = '10';
console.log(+s); // 10
fi
fi
fi
fi
fi
The following example uses the unary plus operator (+) converts a boolean value into a
number, false to 0 and true to 1.

let f = false,
t = true;

console.log(+f); // 0
console.log(+t); // 1

Output:

0
1

Suppose you have a product object with the toString() method as follows:

let person = {
name: 'John',
toString: function () {
return '25';
},
};

console.log(+person);

Output:

25

In this example, we apply the unary plus operator (+) on the person object that has the toString() method,
JavaScript engine calls toString() method to get the value ('25') and convert it into a number. The following
adds the valueOf() method to the person object:

let person = {
name: 'John',
toString: function () {
return '25';
},
valueOf: function () {
return '30';
},
};

console.log(+person);
Output:

30

In this example, the person object has the valueOf() method, the JavaScript engine calls it instead of
the toString() method to get the value to convert.

Unary minus (-)


The unary minus operator is a single minus sign (-). If you apply the unary minus operator to a number, it
negates the number. For example:

let x = 10;
let y = -x;

console.log(y); // -10

If you apply the unary minus operator to a non-numeric value, it converts the value into a
number using the same rules as the unary plus operator and then negates the value.

Increment / Decrement operators


The increment operator has two plus signs (++) while the decrement operator has two minus signs (--).

Both increment and decrement operators have two versions: pre x and post x. And you place the pre x and
post x versions of the increment or decrement operators before and after the variable to which they apply.

The following example uses the pre x increment operator to add one to a variable:

let age = 25;


++age;

console.log(age); // 26

It’s equivalent to the following:

let age = 25;


age = age + 1;
console.log(age); // 26

The following example uses the pre x decrement operator to subtract one from a variable:

let weight = 90;


--weight;

console.log(weight); // 89
fi
fi
fi
fi
fi
fi
It is equivalent to the following:

let weight = 90;


weight = weight - 1;

console.log(weight); // 89

When you apply the pre x increment or decrement, JavaScript changes the variable before
evaluating the statement. For example:

let weight = 90;


weight = ++weight + 5;

console.log(weight); // 96

In this example:
• First, increase the weight on the right-hand side so ++weight is 91
• Second, add ve to the ++weight that returns 96
• Third, assign the result to the weight on the left-hand side.
Likewise, the following example uses a pre x decrement operator:

let weight = 90;


weight = --weight + 5;

console.log(weight); // 94

In this example:

• First, subtract one from the weight, –weight returns 89


• Second, add ve to the –weight that returns 94
• Third, assign the result to the weight on the left-hand side.
The post x increment or decrement operator changes the value after the statement is evaluated. For example:

let weight = 90;


let newWeight = weight++ + 5;

console.log(newWeight); // 95
console.log(weight); // 91
fi
fi
fi
fi
fi
How it works.

• First, add ve to weight (90) and assign the result to the newWeight (95)
• Second, add one to the weight variable after the second statement completes, the weight becomes
91.
• Third, output both newWeight and weight to the console.
When applying the increment/decrement operator to a non-numeric value, it performs the following steps :

• First, convert the value into a number using the same rules as the unary plus (+) operator.
• Then, add one to or subtract one from the value.

Summary
• Unary operators work on one value.
• Unary plus (+) or minus (-) converts a non-numeric value into a number. The unary
minus negates the value after the conversion.
• The pre x increment operator adds one to a value. The value is changed before the
statement is evaluated.
• The post x increment operator adds one to a value. The value is changed after the
statement is evaluated.
• The pre x decrement operator subtracts one from a value. The value is changed before
the statement is evaluated.
• The post x decrement operator subtracts one from a value. The value is changed after
the statement is evaluated.
fi
fi
fi
fi
fi
Comparison operators
Summary: in this tutorial, you will learn how to use JavaScript comparison operators to compare two values.

Introduction to JavaScript comparison operators


To compare two values, you use a comparison operator. The following table shows the comparison operators in JavaScript:

Operator Meaning
< less than
greater than
>
<= less than or equal to
>= greater than or equal to
equal to
!= not equal to

A comparison operator returns a Boolean value indicating that the comparison is true or not.
See the following example:

let r1 = 20 > 10; // true


let r2 = 20 < 10; // false
let r3 = 10 == 10; // true
A comparison operator takes two values. If the types of the values are not comparable, the
comparison operator converts them into values of comparable types according to speci c rules.

Compare numbers
If values are numbers, the comparison operators perform a numeric comparison. For example:

let a = 10,
b = 20;
console.log(a >= b); // false
console.log(a == 10); // true

This example is straightforward. The variable a is 10, b is 20. The expression a >= b expression
returns false and the expression a == 10 expression returns true.

Compare strings
If the operands are strings, JavaScript compares the character codes numerically one by one in the string.

let name1 = 'alice',


name2 = 'bob';

let result = name1 < name2;


console.log(result); // true
console.log(name1 == 'alice'); // true

Because JavaScript compares the character codes in the strings numerically, you may receive an
unexpected result, for example:

let f1 = 'apple',
f2 = 'Banana';
let result = f2 < f1;
console.log(result); // true

In this example, f2 is less than f1 because the letter B has the character code 66 while the letter a has the
character code 97.

To x this, you need to:

• First, convert the strings into a common format, either lowercase or uppercase
• Second, compare the converted values
For example:

let f1 = 'apple',
f2 = 'Banana';
let result = f2.toLowerCase() < f1.toLowerCase();
console.log(result); // false
fi
fi
Note that the toLowerCase() is a method of the String object that converts the string to lowercase.

Compare a number with a value of another type


If a value is a number and the other is not, the comparison operator will convert the non-
numeric value into a number and compare them numerically. For example:

console.log(10 < '20'); // true

In this example, the comparison operator converts the string '20' into the number 20 and compares
with the number 10. Here is an example:

console.log(10 == '10'); // true

In this example, the comparison operator converts the string '10' into the number 10 and compares them
numerically.

Compare an object with a non-object


If a value is an object, the valueOf() method of that object is called to return the value for comparison. If
the object doesn’t have the valueOf() method, the toString() method is called instead. For example:

let apple = {
valueOf: function () {
return 10;
},
};

let orange = {
toString: function () {
return '20';
},
};
console.log(apple > 10); // false
console.log(orange == 20); // true

In this rst comparison, the apple object has the valueOf() method that returns 10. Therefore, the
comparison operator uses the number 10 for comparison.

In the second comparison, JavaScript rst calls the valueOf() method. However, the orange object
doesn’t have the valueOf() method. So JavaScript calls the toString() method to get the returned
value of 20 for comparison.
fi
fi
Compare a Boolean with another value
If a value is a Boolean value, JavaScript converts it to a number and compares the converted value
with the other value; true is converted to 1 and false is converted to 0. For example:

console.log(true > 0); // true


console.log(false < 1); // true
console.log(true > false); // true
console.log(false > true); // false
console.log(true >= true); // true
console.log(true <= true); // true
console.log(false <= false); // true
console.log(false >= false); // true

In addition to the above rules, the equal (==) and not-equal(!=) operators also have the following rules.

Compare null and unde ned


In JavaScript, null equals unde ned. It means that the following expression returns true.

console.log(null == unde ned); // true

Compare NaN with other values


If either value is NaN, then the equal operator(==) returns false.

console.log(NaN == 1); // false

Even

console.log(NaN == NaN); // false

The not-equal (!=) operator returns true when comparing the NaN with another value:

console.log(NaN != 1); // true

And also

console.log(NaN != NaN); // true


fi
fi
fi
Strict equal (===) and not strict equal (!==)
Besides the comparison operators above, JavaScript provides the strict equal ( ===) and not strict
equal ( !==) operators.

Meaning
strict equal. ( ===)
not strict equal. ( !==)

The strict equal and not strict equal operators behave like the equal and not equal operators
except that they don’t convert the operand before comparison. See the following example:

console.log("10" == 10); // true


console.log("10" === 10); // false

In the rst comparison, since we use the equality operator, JavaScript converts the string into the number
and performs the comparison.

However, in the second comparison, we use the strict equal operator ( ===), JavaScript doesn’t convert
the string before comparison, therefore the result is false.

In this tutorial, you have learned how to use the JavaScript comparison operators to compare values.
fi
Logical operators
Summary: in this tutorial, you will learn how to use the JavaScript logical operators including
the logical NOT operator( !), the logical AND operator ( &&) and the logical OR operator ( ||).
The logical operators are important in JavaScript because they allow you to
compare variables and do something based on the result of that comparison.
For example, if the result of the comparison is true, you can run a block of code; if it’s false,
you can execute another code block.
JavaScript provides three logical operators:
• ! (Logical NOT)
• || (Logical OR)
• && (Logical AND)

1) The Logical NOT operator (!)


JavaScript uses an exclamation point ! to represent the logical NOT operator. The ! operator can be
applied to a single value of any type, not just a Boolean value.

When you apply the ! operator to a boolean value, the ! returns true if the value is false and vice
versa. For example:

let eligible = false,


required = true;

console.log(!eligible);
console.log(!required);

Output:

true
false

In this example, the eligible is true so !eligible returns false. And since the required is true,
the !required returns false.
When you apply the ! operator to a non-Boolean value. The ! operator rst converts the value
to a boolean value and then negates it.
The following example shows how to use the ! operator:

!a
fi
The logical ! operator works based on the following rules:

• If a is unde ned, the result is true.


• If a is null, the result is true.
• If a is a number other than 0, the result is false.
• If a is NaN, the result is true.
• If a is an object, the result is false.
• If a is an empty string, the result is true. In the case a is a non-empty string, the result is false
The following demonstrates the results of the logical ! operator when applying to a non-boolean value:

console.log(!unde ned); // true


console.log(!null); // true
console.log(!20); //false
console.log(!0); //true
console.log(!NaN); //true
console.log(!{}); // false
console.log(!''); //true
console.log(!'OK'); //false
console.log(!false); //true
console.log(!true); //false

Double-negation (!!)
Sometimes, you may see the double negation (!!) in the code. The !! uses the logical NOT operator
(!) twice to convert a value to its real boolean value.

The result is the same as using the Boolean() function. For example:

let counter = 10;


console.log(!!counter); // true

The rst ! operator negates the Boolean value of the counter variable. If the counter is true, then
the ! operator makes it false and vice versa.

The second ! operator negates that result of the rst ! operator and returns the real boolean value
of the counter variable.
fi
fi
fi
fi
2) The Logical AND operator (&&)
JavaScript uses the double ampersand (&&) to represent the logical AND operator. The following
expression uses the && operator:

let result = a && b;

If a can be converted to true, the && operator returns the b; otherwise, it returns the a. In fact, this rule is
applied to all boolean values.

The following truth table illustrates the result of the && operator when it is applied to two Boolean values:

a b a && b
TRUE TRUE TRUE
TRUE FALSE FALSE
FALSE TRUE FALSE
FALSE FALSE FALSE

The result of the && operator is true only if both values are true, otherwise, it is false. For example:

let eligible = false,


required = true;

console.log(eligible && required); // false

In this example, the eligible is false, therefore, the value of the expression eligible && required is false.

See the following example:

let eligible = true,


required = true;

console.log(eligible && required); // true

In this example, both eligible and required are true, therefore, the value of the expression eligible &&
required is true.
Short-circuit evaluation
The && operator is short-circuited. It means that the && operator evaluates the second value
only if the rst one doesn’t suf ce to determine the value of an expression. For example:

let b = true;
let result = b && (1 / 0);
console.log(result);

Output:

In nity

In this example, b is true therefore the && operator could not determine the result without further
evaluating the second expression (1/0).

The result is In nity which is the result of the expression (1/0). However:

let b = false;
let result = b && (1 / 0);
console.log(result);

Output:

false

In this case, b is false, the && operator doesn’t need to evaluate the second expression because it
can determine the nal result as false based value of the rst value.

The chain of && operators


The following expression uses multiple && operators:

let result = value1 && value2 && value3;

The && operator carries the following:

• Evaluates values from left to right.


• For each value, converts it to a boolean. If the result is false, stops and returns the original
value.
• If all values are truthy values, returns the last value.
In other words, The && operator returns the rst falsy value or the last value if none were found.
fi
fi
fi
fi
fi
fi
fi
If a value can be converted to true, it is so-called a truthy value. If a value can be converted
to false, it is a so-called falsy value.

3) The Logical OR operator (||)


JavaScript uses the double pipe || to represent the logical OR operator. You can apply the ||
operator to two values of any type:

let result = a || b;

If a can be converted to true, returns a; else, returns b. This rule is also applied to boolean values.

The following truth table illustrates the result of the || operator based on the value of the operands:

a b a || b
TRUE TRUE TRUE
TRUE FALSE TRUE
FALSE TRUE TRUE
FALSE FALSE FALSE

The || operator returns false if both values evaluate to false. In case either value is true, the || operator
returns true. For example:

let eligible = true,


required = false;

console.log(eligible || required); // true

See another example:

let eligible = false,


required = false;

console.log(eligible || required); // false

In this example, the expression eligible || required returns false because both values are false.

The || operator is also short-circuited


Similar to the && operator, the || operator is short-circuited. It means that if the rst value evaluates
to true, the && operator doesn’t evaluate the second one.
fi
The chain of || operators
The following example shows how to use multiple || operators in an expression:

let result = value1 || value2 || value3;

The || operator does the following:

• Evaluates values from left to right.


• For each value, converts it to a boolean value. If the result of the conversion is true, stops and returns the
value.
• If all values have been evaluated to false, returns the last value.
In other words, the chain of the || operators returns the rst truthy value or the last one if no truthy value was found.

Logical operator precedence


When you mix logical operators in an expression, the JavaScript engine evaluates the operators based on
a speci ed order. And this order is called the operator precedence.

In other words, the operator precedence is the order of evaluation of logical operators in an expression.

The precedence of the logical operator is in the following order from the highest to the lowest:

1. Logical NOT (!)

2. Logical AND (&&)

3. Logical OR (||)

Summary
• The NOT operator (!) negates a boolean value. The (!!) converts a value into its real boolean
value.
• The AND operator (&&) is applied to two Boolean values and returns true if both values are
true.
• The OR operator (||) is applied to two Boolean values and returns true if one of the operands
is true.
• Both && and || operator are short-circuited. They can be also applied to non-Boolean values.
• The logical operator precedence from the highest to the lowest is !, && and ||.
fi
fi
Section 3. Control ow Statements

if
Summary: in this tutorial, you will learn how to use the JavaScript if statement to execute a block
when a condition is true.

Introduction to the JavaScript if statement


The if statement executes block if a condition is true. The following shows the syntax of the if statement:

if( condition )
statement;

The condition can be a value or an expression. Typically, the condition evaluates to a Boolean value, which
is true or false.

If the condition evaluates to true, the if statement executes the statement. Otherwise, the if statement passes the
control to the next statement after it.

The following owchart illustrates how the if statement works:

If the condition evaluates to a non-Boolean value, JavaScript implicitly converts its result to a Boolean
value by calling the Boolean() function.
fl
fl
If you have more than one statement to execute, you need to use wrap them in a block using
a pair of curly braces as follows:

if (condition) {
// statements to execute
}

However, it’s a good practice to always use curly braces with the if statement. By doing this,
you make your code easier to maintain and avoid possible mistakes.

JavaScript if statement examples


The following example uses the if statement to check if the age is equal to or greater than 18:

let age = 18;


if (age >= 18) {
console.log('You can sign up');
}

Output:

You can sign up

How it works.
First, declare and initialize the variable age to 18:

let age = 18;

Second, check if the age is greater or equal to 18 using the if statement. Because the expression age >=
18 is true, the code inside the if statement executes that outputs a message to the console:

if (age >= 18) {


console.log('You can sign up');
}

The following example also uses the if statement. However, the age is 16 which causes the condition to
evaluate to false. Therefore, you won’t see any message in the output:

let age = 16;


if (age >= 18) {
console.log('You can sign up');
}
Nested if statement
It’s possible to use an if statement inside another if statement. For example:

let age = 16;


let state = 'CA';

if (state == 'CA') {
if (age >= 16) {
console.log('You can drive.');
}
}

Output:

You can drive.

How it works.
First, declare and initialize the age and state variables:

let age = 16;


let state = 'CA';

Second, check if the state is 'CA' using an if statement. If yes, check if the age is greater than 16 using a
nested if statement and output a message to the console:

if (state == 'CA') {
if (age == 16) {
console.log('You can drive.');
}
}

In practice, you should avoid using nested if statements as much as possible. For example,
you can use the && operator to combine the conditions and use an if statements as follows:

let age = 16;


let state = 'CA';

if (state == 'CA' && age == 16) {


console.log('You can drive.');
}

Summary
• Use the JavaScript if statement to execute a statement if a condition is true.
• Avoid using nested if statement as much as possible.
if…else
Summary: in this tutorial, you will learn how to use the JavaScript if...else statement to execute a
block based on a condition.

Introduction to the JavaScript if…else statement


The if statement executes a block if a condition is true. When the condition is false, it does nothing.
But if you want to execute a statement if the condition is false, you can use an if...else statement.

The following shows the syntax of the if...else statement:

if( condition ) {
// ...
} else {
// ...
}

In this syntax, the condition is a value or an expression that evaluates to true or false. If the condition
is true, the if...else statement executes the block that follows the if branch.

If the condition is false, the if...else statement executes the block that follows the else branch.

Typically, the condition evaluates to a boolean value, which is true or false. However, if it evaluates to a
non-boolean value, the if...else statement will convert it to the boolean value.

The following owchart illustrates how the if...else statement works:


fl
JavaScript if…else statement examples
The following example uses the if...else statement to check if the age is greater than or equal to 18:

let age = 18;

if (age >= 18) {


console.log('You can sign up.');
} else {
console.log('You must be at least 18 to sign up.');
}

In this example, the age is 18. Therefore, the expression age >= 18 is true. Hence, you’ll see the following
message in the console:

You can sign up.

The following example is the same as above except that the age is 18 instead of 16:

let age = 16;

if (age >= 18) {


console.log('You can sign up.');
} else {
console.log('You must be at least 18 to sign up.');
}

Output:

You must be at least 18 to sign up.

In this example, the age is 16. Therefore, the expression age >= 18 evaluates to false. Hence, the
statement in the else branch executes that output the message to the console.

The following example uses a logical operator AND (&&) as the condition in the if block:

let age = 16;


let country = 'USA';

if (age >= 16 && country === 'USA') {


console.log('You can get a driving license.');
} else {
console.log('You are not eligible to get a driving license.');
}
Because the age is 16 and the country is the USA, the following expression returns true.

age >= 16 && country === 'USA'

And you see the following output:

You can get a driving license.

Summary
• Use the JavaScript if...else statement to execute a block if a condition is true and another
block otherwise.
if…else…if
Summary: In this tutorial, you will learn how to use the JavaScript if...else...if statement to check
multiple conditions and execute the corresponding block if a condition is true.

Introduction to the JavaScript if else if statement


The if an if…else statements accept a single condition and execute the if or else block accordingly
based on the condition.

To check multiple conditions and execute the corresponding block if a condition is true, you use
the if...else...if statement like this:

if (condition1) {
// ...
} else if (condition2) {
// ...
} else if (condition3) {
//...
} else {
//...
}

In this syntax, the if...else...if statement has three conditions. In theory, you can have as many conditions
as you want to, where each else...if branch has a condition.

The if...else...if statement checks the conditions from top to bottom and executes the corresponding block
if the condition is true.

The if...else...if statement stops evaluating the remaining conditions as soon as a condition is true. For
example, if the condition2 is true, the if...else...if statement won’t evaluate the condition3.

If all the conditions are false, the if...else...if statement executes the block in the else branch.

The following owchart illustrates how the if...else...if statement works:


fl
JavaScript if else if examples
Let’s take some examples of using the if...else...if statement.

1) A simple JavaScript if…else…if statement example


The following example uses the if...else...if statement to get the month name from a month number:

let month = 6;
let monthName;

if (month == 1) {
monthName = 'Jan';
} else if (month == 2) {
monthName = 'Feb';
} else if (month == 3) {
monthName = 'Mar';
} else if (month == 4) {
monthName = 'Apr';
} else if (month == 5) {
monthName = 'May';
} else if (month == 6) {
monthName = 'Jun';
} else if (month == 7) {
monthName = 'Jul';
} else if (month == 8) {
monthName = 'Aug';
} else if (month == 9) {
monthName = 'Sep';
} else if (month == 10) {
monthName = 'Oct';
} else if (month == 11) {
monthName = 'Nov';
} else if (month == 12) {
monthName = 'Dec';
} else {
monthName = 'Invalid month';
}
console.log(monthName);

Output:

Jun
In this example, we compare the month with 12 numbers from 1 to 12 and assign the corresponding month
name to the monthName variable.

Since the month is 6, the expression month==6 evaluates to true. Therefore, the if...else...if statement
assigns the literal string 'Jun' to the monthName variable. Therefore, you see Jun in the console.

If you change the month to a number that is not between 1 and 12, you’ll see the Invalid Month in the
console because the else clause will execute.

2) Using JavaScript if…else…if statement to calculate the body mass index


The following example calculates a body mass index (BMI) of a person. It uses the if...else...if statement to
determine the weight status based on the BMI:

let weight = 70; // kg


let height = 1.72; // meter

// calculate the body mass index (BMI)


let bmi = weight / (height * height);

let weightStatus;

if (bmi < 18.5) {


weightStatus = 'Underweight';
} else if (bmi >= 18.5 && bmi <= 24.9) {
weightStatus = 'Healthy Weight';
} else if (bmi >= 25 && bmi <= 29.9) {
weightStatus = 'Overweight';
} else {
weightStatus = 'Obesity';
}

console.log(weightStatus);

Output:

Healthy Weight

How it works.
• First, declare two variables that hold the weight in kilogram and height in meter. In a realworld
application, you’ll get these values from a web form.
• Second, calculate the body mass index by dividing the weight by the square of the height.
• Third, determine the weight status based on the BMI using the if...else..if statement.
• Finally, output the weight status to the console.
Summary
• Use the JavaScript if...else...if statement to check multiple conditions and execute the
corresponding block if a condition is true.
Ternary operators
Summary: in this tutorial, you will learn how to use the JavaScript ternary
operator to make your code more concise.

Introduction to JavaScript ternary operator


When you want to execute a block if a condition evaluates to true, you often use an if…else statement. For
example:

let age = 18;


let message;

if (age >= 16) {


message = 'You can drive.';
} else {
message = 'You cannot drive.';
}

console.log(message);

In this example, we show a message that a person can drive if the age is greater than or equal to
16. Alternatively, you can use a ternary operator instead of the if-else statement like this:

let age = 18;


let message;

age >= 16 ? (message = 'You can drive.') : (message = 'You cannot drive.');

console.log(message);

Or you can use the ternary operator in an expression as follows:

let age = 18;


let message;

message = age >= 16 ? 'You can drive.' : 'You cannot drive.';

console.log(message);

Here’s the syntax of the ternary operator:

condition ? expressionIfTrue : expressionIfFalse;


In this syntax, the condition is an expression that evaluates to a Boolean value, either true or false.

If the condition is true, the rst expression (expresionIfTrue) executes. If it is false, the second
expression (expressionIfFalse) executes.

The following shows the syntax of the ternary operator used in an expression:

let variableName = condition ? expressionIfTrue : expressionIfFalse;

In this syntax, if the condition is true, the variableName will take the result of the rst expression
(expressionIfTrue) or expressionIfFalse otherwise.

JavaScript ternary operator examples


Let’s take some examples of using the ternary operator.

1) Using the JavaScript ternary operator to perform multiple statements


The following example uses the ternary operator to perform multiple operations, where each
operation is separated by a comma. For example:

let authenticated = true;


let nextURL = authenticated
? (alert('You will redirect to admin area'), '/admin')
: (alert('Access denied'), '/403');

// redirect to nextURL here


console.log(nextURL); // '/admin'

In this example, the returned value of the ternary operator is the last value in the comma-separated list.

2) Simplifying ternary operator example


See the following example:

let locked = 1;
let canChange = locked != 1 ? true : false;

If the locked is 1, then the canChange variable is set to false, otherwise, it is set to true. In this case,
you can simplify it by using a Boolean expression as follows:

let locked = 1;
let canChange = locked != 1;
fi
fi
3) Using multiple JavaScript ternary operators example
The following example shows how to use two ternary operators in the same expression:

let speed = 90;


let message = speed >= 120 ? 'Too Fast' : speed >= 80 ? 'Fast' : 'OK';

console.log(message);

Output:

Fast

It’s a good practice to use the ternary operator when it makes the code easier to read. If the logic
contains many if...else statements, you should avoid using the ternary operators.

Summary
• Use the JavaScript ternary operator (?:)to make the code more concise.
switch
Summary: in this tutorial, you will learn how to use the JavaScript switch statement to execute a
block based on multiple conditions.

Introduction to the JavaScript switch case statement


The switch statement evaluates an expression, compares its result with case values, and executes
the statement associated with the matching case value.

The following illustrates the syntax of the switch statement:

switch (expression) {
case value1:
statement1;
break;
case value2:
statement2;
break;
case value3:
statement3;
break;
default:
statement;
}

How it works.

• First, evaluate the expression inside the parentheses after the switch keyword.
• Second, compare the result of the expression with the value1, value2, … in
the case branches from top to bottom. The switch statement uses the strict comparison (===).
• Third, execute the statement in the case branch where the result of the expression equals the
value that follows the case keyword. The break statement exits the switch statement. If you
skip the break statement, the code execution falls through the original case branch into the
next one. If the result of the expression does not strictly equal to any value,
the switch statement will execute the statement in the default branch.
That the switch statement will stop comparing the expression‘s result with the remaining case
values as long as it nds a match.

The switch statement is like the if…else…if statement. But it has more readable syntax.

The following owchart illustrates the switch statement:


fl
fi
In practice, you often use a switch statement to replace a complex if...else...if statement to make
the code more readable.

Technically, the switch statement is equivalent to the following if...else...if statement:

if (expression === value1) {


statement1;
} else if (expression === value2) {
statement2;
} else if (expression === value3) {
statement3;
} else {
statement;
}
JavaScript switch case examples
Let’s take some examples of using the JavaScript switch statement.

1) Using JavaScript switch statement to get the day of the week


The following example uses the switch statement to get the day of the week based on a day number:

let day = 3;
let dayName;

switch (day) {
case 1:
dayName = 'Sunday';
break;
case 2:
dayName = 'Monday';
break;
case 3:
dayName = 'Tuesday';
break;
case 4:
dayName = 'Wednesday';
break;
case 5:
dayName = 'Thursday';
break;
case 6:
dayName = 'Friday';
break;
case 7:
dayName = 'Saturday';
break;
default:
dayName = 'Invalid day';
}

console.log(dayName); // Tuesday

Output:

Tuesday
How it works.

First, declare the day variable that holds the day number and the day name variable (dayName).

Second, get the day of the week based on the day number using the switch statement. If the day
is 1, the day of the week is Sunday. If the day is 2, the day of the week is Monday, and so on.

Third, output the day of the week to the console.

2) Using the JavaScript switch statement to get the day count based of a month
The following example uses the switch statement to get the day count of a month:

let year = 2016;


let month = 2;
let dayCount;

switch (month) {
case 1:
case 3:
case 5:
case 7:
case 8:
case 10:
case 12:
dayCount = 31;
break;
case 4:
case 6:
case 9:
case 11:
dayCount = 30;
break;
case 2:
// leap year
if ((year % 4 == 0 && !(year % 100 == 0)) || year % 400 == 0) {
dayCount = 29;
} else {
dayCount = 28;
}
break;
default:
dayCount = -1; // invalid month
}

console.log(dayCount); // 29
In this example, we have four cases:
• If the month is 1, 3,5, 7, 8, 10, or 12, the number of days in a month is 31.
• If the month is 4, 6, 9, or 11, the number of days in that month is 30.
• If the month is 2, and the year is not the leap year, the number of days is 28. If the year
is the leap year, the number of days is 29.
• If the month is not in the valid range (1-12), the default branch executes and sets
the dayCount variable to -1, which indicates the invalid month.

Summary
• The switch statement evaluates an expression, compare its result with case values, and execute the
statement associated with the matching case.
• Use the switch statement to rather than a complex if...else...if statement to make the code more redable.
• The switch statement uses the strict comparison (===) to compare the expression with the case values.
while
Summary: in this tutorial, you will learn how to use the JavaScript while statement to create a loop
that executes a block as long as a condition is true .

Introduction to the JavaScript while loop statement


The JavaScript while statement creates a loop that executes a block as long as a condition evaluates to true.

The following illustrates the syntax of the while statement:

while (expression) {
// statement
}

The while statement evaluates the expression before each iteration of the loop.

If the expression evaluates to true, the while statement executes the statement. Otherwise, the while loop exits.

Because the while loop evaluates the expression before each iteration, it is known as a pretest loop.

If the expression evaluates to false before the loop enters, the while loop will never execute.

The following owchart illustrates the while loop statement:

Note that if you want to execute the statement a least once and check the condition after each
iteration, you should use the do…while statement.
fl
JavaScript while loop example
The following example uses the while statement to output the odd numbers between 1 and 10 to the console:

let count = 1;
while (count < 10) {
console.log(count);
count +=2;
}

Output:

1
3
5
7
9

How the script works

• First, declare and initialize the count variable to 1.


• Second, execute the statement inside the loop if the count variable is less than 10. In each iteration,
ouput the count to the console and increase the count by 2.
• Third, after 5 iterations, the count is 11. Therefore, the condition count < 10 is false, the loop exits.

Summary
• Use a while loop statement to create a loop that executes a block as long as a condition evaluates to true.
do…while
Summary: in this tutorial, you will learn how to use the JavaScript do...while statement to create a
loop that executes a block until a condition is false.

Introduction to the JavaScript do…while statement


The do...while loop statement creates a loop that executes a block until a condition evaluates to false. The
following statement illustrates the syntax of the do...while loop:

do {
statement;
} while(expression);

Unlike the while loop, the do-while loop always executes the statement at least once before evaluating the expression.

Because the do...while loop evaluates expression after each iteration, it’s often referred to as a post-test loop.

Inside the loop body, you need to make changes to some variables to ensure that
the expression is false after some iterations. Otherwise, you’ll have an inde nite loop.

Note that starting with ES6+, the trailing semicolon (;) after the while(expression) is optional. So you can
use the following syntax:

do {
statement;
} while(expression)

The following owchart illustrates the do-while loop statement:

In practice, you often use the do...while statement when you want to execute the loop body at least
once before checking the condition.
fl
fi
JavaScript do while statement examples
Let’s take some examples of using the do...while statement.

1) Simple JavaScript do while statement example


The following example uses the do...while statement to output ve numbers from 0 to 4 to the console:

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

Output:

0
1
2
3
4

In this example:

• First, declare and initialize the count variable to zero.


• Second, show the count and increase its value by one in each iteration until its value is greater or equal to 5.
fi
2) Using the JavaScript do while statement to make a simple number guessing game
The following example uses the do...while statement to generate a number guessing game.
The script generates a random integer between 1 and 10. And you have to make a number of
guesses until your number matches the random number.

// generate a secret number between 1 and 10


const MIN = 1;
const MAX = 10;

let secretNumber = Math. oor(Math.random() * (MAX - MIN + 1)) + MIN;

let guesses = 0; // for storing the number of guesses


let hint = ''; // for storing hint
let number = 0;
do {
// get input from user
let input = prompt(`Please enter a number between ${MIN} and ${MAX}` + hint);

// get the integer


number = parseInt(input);

// increase the number of guesses


guesses++;

// check input number with the secret number provide hint if needed
if (number > secretNumber) {
hint = ', and less than ' + number;
} else if (number < secretNumber) {
hint = ', and greater than ' + number;
} else if (number == secretNumber) {
alert(`Bravo! you're correct after ${guesses} guess(es).`);
}
} while (number != secretNumber);

How it works.
First, declare the MIN and MAX constants and initialize their values to 1 and 10:

const MIN = 1;
const MAX = 10;

Second, use Math.random() function to generate a random oating-point number with the value in the
range of 0 and 1 (inclusive of zero but not one).

To generate a random number between MIN and MAX (exclusive), you use the following expression:

Math.random() * (MAX - MIN + 1)


fl
fl
However, the result is a oating-point number. Therefore, you need to use the Math. oor() function
to convert it to an integer:

Math. oor(Math.random() * (MAX - MIN + 1))

To generate a random number between min and max, you use the following expression:

let secretNumber = Math. oor(Math.random() * (MAX - MIN + 1)) + MIN;

Third, de ne three variables for storing the number of guesses, hints, and user’s input number:

let guesses = 0; // for storing the number of guesses


let hint = ''; // for storing hint
let number = 0;

Fourth, use the input() function to get the input from the user:

let input = prompt(`Please enter a number between ${MIN} and ${MAX}` + hint);

Note that the input() function only works on web browsers. If you run the code in another environment such as
node.js, please check the corresponding function.

The input() function returns a string, therefore, you need to use the parseInt() function to convert it to an integer:

number = parseInt(input);

Fifth, increase the number of guesses in each iteration:

guesses++;

Sixth, check the input number with the secret number (random) number and give hint. If the
numbers are matched, show the message using the alert() function:

if (number > secretNumber) {


hint = ', and less than ' + number;
} else if (number < secretNumber) {
hint = ', and greater than ' + number;
} else if (number == secretNumber) {
alert(`Bravo! you're correct after ${guesses} guess(es).`);
}

Seventh, perform the next iteration until the number matches the secret number.

Summary
• Use the do…while statement to create a loop that executes a code block until a condition is false.
fl
fi
fl
fl
fl
for loop
Summary: in this tutorial, you will learn how to use the JavaScript for loop statement to create a
loop with various options.

Introduction to the JavaScript for loop statement


The for loop statement creates a loop with three optional expressions. The following illustrates the
syntax of the for loop statement:

for (initializer; condition; iterator) {


// statements
}

1) initializer
The for statement executes the initializer only once the loop starts. Typically, you declare and initialize a
local loop variable in the initializer.

2) condition
The condition is a boolean expression that determines whether the for should execute the next iteration.

The for statement evaluates the condition before each iteration. If the condition is true (or is not present), it
executes the next iteration. Otherwise, it’ll end the loop.

3) iterator
The for statement executes the iterator after each iteration.

The following owchart illustrates the for loop:


fl
In the for loop, the three expressions are optional. The following shows the for loop without any expressions:

for ( ; ; ) {
// statements
}

JavaScript for loop examples


Let’s take some examples of using the for loop statement.

1) A simple JavaScript for loop example


The following example uses the for loop statement to show numbers from 1 to 4 to the console:

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


console.log(i);
}

Output:

1
2
3
4

How it works.
• First, declare a variable counter and initialize it to 1.
• Second, display the value of counter in the console if counter is less than 5.
• Third, increase the value of counter by one in each iteration of the loop.
2) Using the JavaScript for loop without the initializer example
The following example uses a for loop that has no initializer expression:

let j = 1;
for (; j < 10; j += 2) {
console.log(j);
}

Output:

1
3
5
7
9

3) Using the JavaScript for loop without the condition example


Similar to the initializer expression, the condition expression is optional. If you omit the condition expression, you
need to use a break statement to terminate the loop.

for (let j = 1; ; j += 2) {
console.log(j);
if (j > 10) {
break;
}
}

Output:

1
3
5
7
9
11
3) Using the JavaScript for loop statement without any expression example
All three expressions of the for loop statements are optional. Therefore, you can omit all of them. For example:

let j = 1;
for (;;) {
if (j > 10) {
break;
}
console.log(j);
j += 2;
}

Output:

1
3
5
7
9

4) Using the JavaScript for loop without the loop body example
JavaScript allows the for statement to have an empty statement. In this case, you place a semicolon (;)
immediately after the for statement.

For example, the following uses a for loop to calculate the sum of 10 numbers from 1 to 10:

let sum = 0;
for (let i = 0; i <= 9; i++, sum += i);
console.log(sum);

Output:

55

Summary
• Use the JavaScript for statement to create a loop that executes a block of code using various options.
break
Summary: in this tutorial, you’ll learn how to use the JavaScript break statement to terminate
a loop prematurely.

The label statement


In JavaScript, you can label a statement for later use. Here’s the syntax of the label statement:

label: statement;

In this syntax, the label can be any valid identi er. For example, the following shows how to label a for loop
using the outer label:

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


console.log(i);
}

Once de ning a label, you can reference it in the break or continue statement.

Introduction to JavaScript break statement


The break statement prematurely terminates a loop such as for, do...while, and while loop, a switch,
or a label statement. Here’s the syntax of the break statement:

break [label];

In this syntax, the label is optional if you use the break statement in a loop or switch. However, if you use
the break statement with a label statement, you need to specify it.

This tutorial focuses on how to use the break statement to terminate the loop prematurely.
fi
fi
Using JavaScript break statement in a for loop
The following for loop statement outputs ve numbers from 0 to 4:

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


console.log(i);
}

Output:

0
1
2
3
4

To terminate the for loop prematurely, you can use a break statement. For example, the following
illustrates how to use a break statement inside a for loop:

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


console.log(i);
if (i == 2) {
break;
}
}

Output:

0
1
2

In this example, we use an if statement inside the loop. If the current value of i is 2, the if statement
executes the break statement that terminates the loop.

This owchart illustrates how the break statement works in a for loop:
fl
fi
Using the break statement to terminate a nested loop
A nested loop has one loop inside another. For example, the following uses a nested for loop to output a
pair of numbers from 1 to 3:

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


for (let j = 1; j <= 3; j++) {
console.log(i, j);
}
}

Output:

11
12
13
21
22
23
31
32
33
If you use a break statement inside an inner loop, it only terminates the enclosing loop. For example:

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


for (let j = 1; j <= 3; j++) {
if (i + j == 4) {
break;
}
console.log(i, j);
}
}

Output:

11
12
21

In this example, if the sum of i and j is 4, the break statement terminates the inner loop. To terminate
the nested loop, you use a label statement. For example:

outer: for (let i = 1; i <= 3; i++) {


for (let j = 1; j <= 3; j++) {
if (i + j == 4) {
break outer;
}
console.log(i, j);
}
}

Output:

11
12

In this example, we label the outer loop with the label outer. Inside the inner loop, we specify the outer label
in the break statement. The break statement to terminate the nested loop if the sum of i and j is 4.
Using JavaScript break statement in a while loop
The following output ve numbers from 1 to 5 to the console using a while loop:

let i = 0;

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

Output:

1
2
3
4
5

Like a for loop, the break statement terminates a while loop prematurely. For example:

let i = 0;

while (i < 5) {
i++;
console.log(i);
if (i == 3) {
break;
}
}

Output:

1
2
3

In this example, when the current value of i is 3, the break statement terminates the loop. Therefore, you
see only three numbers in the output.
fi
The following owchart illustrates how the break statement works in a while loop:

Using JavaScript break statement in a do…while loop


The following example uses a do...while statement to output ve numbers from 0 to 5 to the console:

let i = 0;

do {
i++;
console.log(i);
} while (i < 5);

Output:

1
2
3
4
5
fl
fi
Like a while loop, you can use a break statement to terminate a do...while loop. For example:

let i = 0;

do {
i++;
console.log(i);
if (i == 3) {
break;
}
} while (i < 5);

Output:

1
2
3

The following owchart shows how the break statement works in a do while loop:

Summary
• Use the break statement to terminate a loop including for, while, and do...while prematurely.
• When used in a nested loop, the break statement terminates the enclosing loop. To terminate
the nested loop, you use a label statement.
fl
continue
Summary: in this tutorial, you will learn how to use the JavaScript continue statement to skip the
current iteration of a loop.

Introduction to the JavaScript continue statement


The continue statement terminates the execution of the statement in the current iteration of a loop
such as a for, while, and do…while loop and immediately continues to the next iteration.

Here’s the syntax of the continue statement:

continue [label];

In this syntax, the label is optional. It is a valid identi er associated with the label of a statement.
Read the break statement tutorial for more information on the label statement.

Typically, you use the continue with an if statement like this:

// inside a loop
if(condition){
continue;
}

In this syntax, the if statement speci es a condition to execute the continue statement inside a loop.
fi
fi
Using the continue statement in a for loop
When using the continue statement in a for loop, it doesn’t terminate the loop entirely. Instead, it jumps to
the iterator expression.

The following owchart illustrates how the continue statement works in a for loop:

The following example uses a continue in a for loop to display the odd number in the console:

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


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

Output:

1
3
5
7
9
fl
In this example, the for loop iterates over the numbers from 0 to 9.

The i%2 returns the remainder of the division of the current value of i by 2.

If the remainder is zero, the if statement executes the continue statement that skips the current iteration of
the loop and jumps to the iterator expression i++. Otherwise, it outputs the value of i to the console.

Using the continue statement in a while loop


When using the continue statement in a while loop, it doesn’t terminate the execution of the loop entirely.
Instead, it jumps back to the condition.

The following owchart show hows the continue statement works in a while loop statement:

The following example uses the continue statement in a while loop to display the odd numbers from 1 to 10:

let i = 0;
while (i < 10) {
i++;
if (i % 2 === 0) {
continue;
}
console.log(i);
}
fl
Output:

1
3
5
7
9

Using the continue statement with a label example


The continue statement can include an optional label like this:

continue label;

The following nested loop displays pairs of numbers from 1 to 2:

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


for (let j = 1; j < 3; j++) {
console.log(i, j);
}
}

Output:

11
12
21
22

The following shows how to use the continue statement with a label:

outer: for (let i = 1; i < 4; i++) {


for (let j = 1; j < 4; j++) {
if (i + j == 3) continue outer;
console.log(i, j);
}
}

Output:

11
31
32
33

Summary
• Use the JavaScript continue statement to skip the current iteration of a loop and continue the next one.
Comma operator
Summary: in this tutorial, you’ll learn about the JavaScript comma operator and its usage.

Introduction to the JavaScript comma operator


JavaScript uses a comma (,) to represent the comma operator. A comma operator takes two
expressions, evaluates them from left to right, and returns the value of the right expression.
Here’s the syntax of the comma operator:

leftExpression, rightExpression

For example:

let result = (10, 10 + 20);


console.log(result);

Output:

30

In this example, the 10, 10+20 returns the value of the right expression, which is 10+20.
Therefore, the result value is 30.
See the following example:

let x = 10;
let y = (x++, x + 1);

console.log(x, y);

Output:

11 12

In this example, we increase the value of x by one (x++), add one to x (x+1) and assign x to y. Therefore, x is 11,
and y is 12 after the statement.

However, to make the code more explicit, you can use two statements rather than one statement with a comma
operator like this:

let x = 10;
x++;
let y = x + 1;

console.log(x, y);
This code is more explicit.

In practice, you might want to use the comma operator inside a for loop to update multiple variables
each time through the loop.

The following example uses the comma operator in a for loop to display an array of nine elements
as a matrix of 3 rows and three columns:

let board = [1, 2, 3, 4, 5, 6, 7, 8, 9];

let s = '';
for (let i = 0, j = 1; i < board.length; i++, j++) {
s += board[i] + ' ';
if (j % 3 == 0) {
console.log(s);
s = '';
}
}

Output:

123
456
789

Summary
• A comma operator takes two expressions and evaluates them from left to right, and
returns the value of the right expression.
• Use the comma operator (,) inside a for loop to update multiple variables once.
• Use two statements rather than the comma operator elsewhere to make the code more
explicit and easier to understand.
Section 4. Functions

Functions
Summary: in this tutorial, you will learn about JavaScript functions and how to use them to
structure the code into smaller and more reusable units.

Introduction to JavaScript functions


When developing an application, you often need to perform the same action in many places. For example,
you may want to show a message whenever an error occurs.

To avoid repeating the same code all over places, you can use a function to wrap that code and reuse it.

JavaScript provides many built-in functions such as parseInt() and parseFloat(). In this tutorial, you will
learn how to develop custom functions.

Declare a function
To declare a function, you use the function keyword, followed by the function name, a list of parameters,
and the function body as follows:

function functionName(parameters) {
// function body
// ...
}

The function name must be a valid JavaScript identi er. By convention, the function names are in
camelCase and start with verbs like getData(), fetchContents(), and isValid().

A function can accept zero, one, or multiple parameters. In the case of multiple parameters, you
need to use a comma to separate two parameters.

The following declares a function say() that accepts no parameter:

function say() {
}

The following declares a function named square() that accepts one parameter:

function square(a) {
}
fi
And the following declares a function named add() that accepts two parameters:

function add(a, b) {
}

Inside the function body, you can write the code to implement an action. For example, the following say() function
simply shows a message to the console:

function say(message) {
console.log(message);
}

In the body of the say() function, we call the console.log() function to output a message to the console.

Calling a function
To use a function, you need to call it. Calling a function is also known as invoking a function.
To call a function, you use its name followed by arguments enclosing in parentheses like this:

functionName(arguments);

When calling a function, JavaScript executes the code inside the function body. For example,
the following shows how to call the say() function:

say('Hello');

In this example, we call the say() function and pass a literal string 'Hello' into it.

Parameters vs. Arguments


The terms parameters and arguments are often used interchangeably. However, they are
essentially different.
When declaring a function, you specify the parameters. However, when calling a function,
you pass the arguments that are corresponding to the parameters.
For example, in the say() function, the message is the parameter and the 'Hello' string is an
argument that corresponds to the message parameter.
Returning a value
Every function in JavaScript implicitly returns unde ned unless you explicitly specify a return value. For example:

function say(message) {
console.log(message);
}

let result = say('Hello');


console.log('Result:', result);

Output:

Hello
Result: unde ned

To specify a return value for a function, you use the return statement followed by an expression or a
value, like this:

return expression;

For example, the following add() function returns the sum of the two arguments:

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

The following shows how to call the add() function:

let sum = add(10, 20);


console.log('Sum:', sum);

Output:

Sum: 30

The following example uses multiple return statements in a function to return different values based on conditions:

function compare(a, b) {
if (a > b) {
return -1;
} else if (a < b) {
return 1;
}
return 0;
}
fi
fi
The compare() function compares two values. It returns:

• -1 if the rst argument is greater than the second one.


• 1 if the rst argument is less than the second one.
• 0 if the rst argument equals the second one.
The function immediately stops executing immediately when it reaches the return statement. Therefore,
you can use the return statement without a value to exit the function prematurely, like this:

function say(message) {
// show nothing if the message is empty
if (! message ) {
return;
}
console.log(message);
}

In this example, if the message is blank (or unde ned), the say() function will show nothing.
The function can return a single value. If you want to return multiple values from a function,
you need to pack these values in an array or an object.

The arguments object


Inside a function, you can access an object called arguments that represents the named arguments of the function.

The arguments object behaves like an array though it is not an instance of the Array type.

For example, you can use the square bracket [] to access the arguments: arguments[0] returns the rst
argument, arguments[1] returns the second one, and so on.

Also, you can use the length property of the arguments object to determine the number of arguments.

The following example implements a generic add() function that calculates the sum of any number of arguments.

function add() {
let sum = 0;
for (let i = 0; i < arguments.length; i++) {
sum += arguments[i];
}
return sum;
}

Hence, you can pass any number of arguments to the add() function, like this:

console.log(add(1, 2)); // 3
console.log(add(1, 2, 3, 4, 5)); // 15
fi
fi
fi
fi
fi
Function hoisting
In JavaScript, you can use a function before declaring it. For example:

showMe(); // a hoisting example

function showMe(){
console.log('an hoisting example');
}

This feature is called hoisting.


Function hoisting is a mechanism that the JavaScript engine physically moves function
declarations to the top of the code before executing them.
The following shows the version of the code before the JavaScript engine executes it:

function showMe(){
console.log('a hoisting example');
}

showMe(); // a hoisting example

Summary
• Use the function keyword to declare a function.
• Use the functionName() to call a function.
• All functions implicitly return unde ned if they don’t explicitly return a value.
• Use the return statement to return a value from a function explicitly.
• The arguments variable is an array-like object inside a function, representing function
arguments.
• The function hoisting allows you to call a function before declaring it.
fi
Functions are the rst-class citizens
Summary: in this tutorial, you’ll learn that JavaScript functions are rst-class citizens. This
means that you can store functions in variables, pass them to other functions as arguments,
and return them from other functions as values.

Storing functions in variables


Functions are rst-class citizens in JavaScript. In other words, you can treat functions like values of other types.

The following de nes the add() function and assigns the function name to the variable sum:

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

let sum = add;

In the assignment statement, we don’t include the opening and closing parentheses at the end of the add identi er.
We also don’t execute the function but reference the function.

By doing this, we can have two ways to execute the same function. For example, we can call it normally as follows:

let result = add(10, 20);

Alternatively, we can all the add() function via the sum variable like this:

let result = sum(10,20);

Passing a function to another function


Because functions are values, you can pass a function as an argument into another function.

The following declares the average() function that takes three arguments. The third argument is a function:

function average(a, b, fn) {


return fn(a, b) / 2;
}

Now, you can pass the sum function to the average() function as follows:

let result = average(10, 20, sum);


fi
fi
fi
fi
fi
Put it all together:

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

let sum = add;

function average(a, b, fn) {


return fn(a, b) / 2;
}

let result = average(10, 20, sum);

console.log(result);

Output:

15

Returning functions from functions


Since functions are values, you can return a function from another function.

The following compareBy() function returns a function that compares two objects by a property:

function compareBy(propertyName) {
return function (a, b) {
let x = a[propertyName],
y = b[propertyName];

if (x > y) {
return 1;
} else if (x < y) {
return -1;
} else {
return 0;
}
};
}

Note that a[propertyName] returns the value of the propertyName of the a object. It’s
equivalent to a.propertyName. However, if the propertyName contains a space
like 'Discount Price', you need to use the square bracket notation to access it.
Suppose that you have an array of product objects where each product object has two properties: name and price.

let products = [
{name: 'iPhone', price: 900},
{name: 'Samsung Galaxy', price: 850},
{name: 'Sony Xperia', price: 700}
];

You can sort an array by calling the sort() method. The sort() method accepts a function that compares two
elements of the array as an argument.

For example, you can sort the product objects based on the name by passing a function returned from
the compareBy() function as follows:

console.log('Products sorted by name:');


products.sort(compareBy('name'));

console.table(products);

Output:

(index) name price


0 Samsung Galaxy' 850
1 Sony Xperia' 700
2 iPhone' 900

Similarly, you can sort the product objects by prices:

// sort products by prices

console.log('Products sorted by price:');


products.sort(compareBy('price'));
console.table(products);

Output:
Products sorted by price:
(index) name price
0 Sony Xperia' 700
1 Samsung Galaxy' 850
2 'iPhone' 900
Put it all together.

function compareBy(propertyName) {
return function (a, b) {
let x = a[propertyName],
y = b[propertyName];
if (x > y) {
return 1;
} else if (x < y) {
return -1;
} else {
return 0;
}
};
}
let products = [
{ name: 'iPhone', price: 900 },
{ name: 'Samsung Galaxy', price: 850 },
{ name: 'Sony Xperia', price: 700 },
];
// sort products by name
console.log('Products sorted by name:');
products.sort(compareBy('name'));
console.table(products);
// sort products by price
console.log('Products sorted by price:');
products.sort(compareBy('price'));
console.table(products);

More JavaScript Functions are First-Class Citizens example


The following example de nes two functions that convert a length in centimeters to inches and vice versa:

function cmToIn(length) {
return length / 2.54;
}

function inToCm(length) {
return length * 2.54;
}

The following convert() function has two parameters. The rst parameter is a function and the
second one is the length that will be converted based on the rst argument:

function convert(fn, length) {


return fn(length);
}
fi
fi
fi
To convert cm to in, you can call the convert() function and pass the cmToIn function into the convert() function as
the rst argument:

let inches = convert(cmToIn, 10);


console.log(inches);

Output:

3.937007874015748

Similarly, to convert a length from inches to centimeters, you can pass the inToCm function
into the convert() function, like this:

let cm = convert(inToCm, 10);


console.log(cm);

Output:

25.4

Put it all together.

function cmToIn(length) {
return length / 2.54;
}
function inToCm(length) {
return length * 2.54;
}
function convert(fn, length) {
return fn(length);
}
let inches = convert(cmToIn, 10);
console.log(inches);
let cm = convert(inToCm, 10);
console.log(cm);

Output:

3.937007874015748
25.4

Summary
• Functions are rst-class citizens in JavaScript.
• You can pass functions to other functions as arguments, return them from other functions as values,
and store them in variables.
fi
fi
Anonymous Functions
Summary: in this tutorial, you will learn about JavaScript anonymous functions.

Introduction to JavaScript anonymous functions


An anonymous function is a function without a name. The following shows how to de ne an anonymous function:

(function () {
//...
});

Note that if you don’t place the anonymous function inside the (), you’ll get a syntax error. The () makes
the anonymous function an expression that returns a function object.
An anonymous function is not accessible after its initial creation. Therefore, you often need to assign it to a variable.

For example, the following shows an anonymous function that displays a message:

let show = function() {


console.log('Anonymous function');
};

show();

In this example, the anonymous function has no name between the function keyword and parentheses ().

Because we need to call the anonymous function later, we assign the anonymous function to
the show variable.

Since the whole assignment of the anonymous function to the show variable makes a valid expression,
you don’t need to wrap the anonymous function inside the parentheses ().

Using anonymous functions as arguments


In practice, you often pass anonymous functions as arguments to other functions. For example:

setTimeout(function() {
console.log('Execute later after 1 second')
}, 1000);

In this example, we pass an anonymous function into the setTimeout() function. The setTimeout() function
executes this anonymous function one second later.

Note that functions are rst-class citizens in JavaScript. Therefore, you can pass a
function to another function as an argument.
fi
fi
Immediately invoked function execution
If you want to create a function and execute it immediately after the declaration, you can
declare an anonymous function like this:

(function() {
console.log('IIFE');
})();

How it works.
First, de ne a function expression:

(function () {
console.log('Immediately invoked function execution');
})

This expression returns a function.

Second, call the function by adding the trailing parentheses ():

(function () {
console.log('Immediately invoked function execution');
})();

and sometimes, you may want to pass arguments into it, like this:

let person = {
rstName: 'John',
lastName: 'Doe'
};

(function () {
console.log(person. rstName} + ' ' + person.lastName);
})(person);

Summary
• Anonymous functions are functions without names.
• Anonymous functions can be used as an argument to other functions or as an immediately
invoked function execution.
fi
fi
fi
Pass-by-value
Summary: this tutorial explains how JavaScript pass-by-value works and gives you some
examples of passing primitive and reference values to a function.

Before going forward with this tutorial, you should have good knowledge of the primitive
and reference values, and the differences between them.

JavaScript pass-by-value or pass-by-reference


In JavaScript, all function arguments are always passed by value. It means that JavaScript
copies the values of the variables into the function arguments.
Any changes that you make to the arguments inside the function do not re ect the passing
variables outside of the function. In other words, the changes made to the arguments are not
re ected outside of the function.
If function arguments are passed by reference, the changes of variables that you pass into
the function will be re ected outside the function. This is not possible in JavaScript.

Pass-by-value of primitives values


Let’s take a look at the following example.

function square(x) {
x = x * x;
return x;
}

let y = 10;
let result = square(y);

console.log(result); // 100
console.log(y); // 10 -- no change

How the script works.

First, de ne a square() function that accepts an argument x. The function assigns the square of x to
the x argument.

Next, declare the variable y and initialize its value to 10:


fl
fi
fl
fl
Then, pass the y variable into the square() function. When passing the variable y to the square() function,
JavaScript copies y value to the x variable.

After that, the square() function changes the x variable. However, it does not impact the value
of the y variable because x and y are separate variables.

Finally, the value of the y variable does not change after the square() function completes.

If JavaScript used the pass-by-reference, the variable y would change to 100 after calling the function.
Pass-by-value of reference values
It’s not obvious to see that reference values are also passed by values. For example:

let person = {
name: 'John',
age: 25,
};

function increaseAge(obj) {
obj.age += 1;
}

increaseAge(person);

console.log(person);

How the script works:

First, de ne the person variable that references an object with two properties name and age:

Next, de ne the increaseAge() function that accepts an object obj and increases the age property
of the obj argument by one.

Then, pass the person object to the increaseAge() function:


fi
fi
Internally, the JavaScript engine creates the obj reference and make this variable reference
the same object that the person variable references.

After that, increase the age property by one inside the increaseAge() function via the obj variable

Finally, accessing the object via the person reference:

It seems that JavaScript passes an object by reference because the change to the object is
re ected outside the function. However, this is not the case.
In fact, when passing an object to a function, you are passing the reference of that object, not
the actual object. Therefore, the function can modify the properties of the object via its
reference.
However, you cannot change the reference passed into the function. For example:

let person = {
name: 'John',
age: 25,
};
function increaseAge(obj) {
obj.age += 1;
// reference another object
obj = { name: 'Jane', age: 22 };
}
increaseAge(person);
console.log(person);
fl
Output:

{ name: 'John', age: 26 }

In this example, the increaseAage() function changes the age property via the obj argument:

and makes the obj reference another object:

However, the person reference still refers to the original object whose the age property changes to 26. In
other words, the increaseAge() function doesn’t change the person reference.

If this concept still confuses you, you can consider function arguments as local variables.

Summary
• JavaScript passes all arguments to a function by values.
• Function arguments are local variables in JavaScript.
Recursive function
Summary: in this tutorial, you will learn how to use the recursion technique to develop a
JavaScript recursive function, which is a function that calls itself.

Introduction to the JavaScript recursive functions


A recursive function is a function that calls itself until it doesn’t. And this technique is called recursion.

Suppose that you have a function called recurse(). The recurse() is a recursive function if it calls itself
inside its body, like this:

function recurse() {
// ...
recurse();
// ...
}

A recursive function always has a condition to stop calling itself. Otherwise, it will call itself
inde nitely. So a recursive function typically looks like the following:

function recurse() {
if(condition) {
// stop calling itself
//...
} else {
recurse();
}
}

Generally, you use recursive functions to break down a big problem into smaller ones. Typically,
you will nd the recursive functions in data structures like binary trees and graphs and algorithms
such as binary search and quicksort.
fi
fi
JavaScript recursive function examples
Let’s take some examples of using recursive functions.

1) A simple JavaScript recursive function example


Suppose that you need to develop a function that counts down from a speci ed number to 1.
For example, to count down from 3 to 1:

3
2
1

The following shows the countDown() function:

function countDown(fromNumber) {
console.log(fromNumber);
}

countDown(3);

This countDown(3) shows only the number 3.

To count down from the number 3 to 1, you can:

1. show the number 3.

2. and call the countDown(2) that shows the number 2.

3. and call the countDown(1) that shows the number 1.

The following changes the countDown() to a recursive function:

function countDown(fromNumber) {
console.log(fromNumber);
countDown(fromNumber-1);
}

countDown(3);

This countDown(3) will run until the call stack size is exceeded, like this:

Uncaught RangeError: Maximum call stack size exceeded.

… because it doesn’t have the condition to stop calling itself.


fi
The count down will stop when the next number is zero. Therefore, you add an if condition as follows:

function countDown(fromNumber) {
console.log(fromNumber);

let nextNumber = fromNumber - 1;

if (nextNumber > 0) {
countDown(nextNumber);
}
}
countDown(3);

Output:

3
2
1

The countDown() seems to work as expected.

However, as mentioned in the Function type tutorial, the function’s name is a reference to the actual
function object.

If the function name is set to null somewhere in the code, the recursive function will stop working.

For example, the following code will result in an error:

let newYearCountDown = countDown;


// somewhere in the code
countDown = null;
// the following function call will cause an error
newYearCountDown(10);

Error:

Uncaught TypeError: countDown is not a function

How the script works:

• First, assign the countDown function name to the variable newYearCountDown.


• Second, set the countDown function reference to null.
• Third, call the newYearCountDown function.
The code causes an error because the body of the countDown() function references
the countDown function name, which was set to null at the time of calling the function.
To x it, you can use a named function expression as follows:

let countDown = function f(fromNumber) {


console.log(fromNumber);

let nextNumber = fromNumber - 1;

if (nextNumber > 0) {
f(nextNumber);
}
}

let newYearCountDown = countDown;


countDown = null;
newYearCountDown(10);

2) Calculate the sum of n natural numbers example


Suppose you need to calculate the sum of natural numbers from 1 to n using the recursion
technique. To do that, you need to de ne the sum() recursively as follows:

sum(n) = n + sum(n-1)
sum(n-1) = n - 1 + sum(n-2)
...
sum(1) = 1

The following illustrates the sum() recursive function:

function sum(n) {
if (n <= 1) {
return n;
}
return n + sum(n - 1);
}

Summary
• A recursive function is a function that calls itself until it doesn’t
• A recursive function always has a condition that stops the function from calling itself.
fi
fi
Section 5. Objects & Prototypes

Object Methods
Summary: in this tutorial, you’ll learn about the JavaScript object methods and how to de ne
methods for an object.

Introduction to the JavaScript object methods


An object is a collection of key/value pairs or properties. When the value is a function, the
property becomes a method. Typically, you use methods to describe the object behaviors.
For example, the following adds the greet method to the person object:

let person = {
rstName: 'John',
lastName: 'Doe'
};
person.greet = function () {
console.log('Hello!');
}
person.greet();

Output:

Hello!

In this example:

• First, use a function expression to de ne a function and assign it to the greet property of
the person object.
• Then, call the method greet() method.
Besides using a function expression, you can de ne a function and assign it to an object like this:

let person = {
rstName: 'John',
lastName: 'Doe'
};
function greet() {
console.log('Hello, World!');
}
person.greet = greet;
person.greet();
fi
fi
fi
fi
fi
In this example:
• First, de ne the greet() function as a regular function.
• Second, assign the function name to the the greet property of the person object.
• Third, call the greet() method.

Object method shorthand


JavaScript allows you to de ne methods of an object using the object literal syntax as shown
in the following example:

let person = {
rstName: 'John',
lastName: 'Doe',
greet: function () {
console.log('Hello, World!');
}
};

ES6 provides you with the concise method syntax that allows you to de ne a method for an object:

let person = {
rstName: 'John',
lastName: 'Doe',
greet() {
console.log('Hello, World!');
}
};

person.greet();

This syntax looks much cleaner and less verbose.

The this value


Typically, methods need to access other properties of the object.

For example, you may want to de ne a method that returns the full name of the person object by
concatenating the rst name and last name.

Inside a method, the this value references the object that invokes the method. Therefore, you can access
a property using the this value as follows:

this.propertyName
fi
fi
fi
fi
fi
fi
fi
The following example uses the this value in the getFullName() method:

let person = {
rstName: 'John',
lastName: 'Doe',
greet: function () {
console.log('Hello, World!');
},
getFullName: function () {
return this. rstName + ' ' + this.lastName;
}
};

console.log(person.getFullName());

Output

'John Doe'

Check out this tutorial for more information on this value.

Summary
• When a function is a property of an object, it becomes a method.
fi
fi
Constructor functions
Summary: in this tutorial, you’ll learn about the JavaScript constructor function and how to
use the new keyword to create an object.

Introduction to JavaScript constructor functions


In the JavaScript objects tutorial, you learned how to use the object literal syntax to create a new object.

For example, the following creates a new person object with two properties rstName and lastName:

let person = {
rstName: 'John',
lastName: 'Doe'
};

In practice, you often need to create many similar objects like the person object.

To do that, you can use a constructor function to de ne a custom type and the new operator to
create multiple objects from this type.

Technically speaking, a constructor function is a regular function with the following convention:

• The name of a constructor function starts with a capital letter like Person, Document, etc.
• A constructor function should be called only with the new operator.

Note that ES6 introduces the class keyword that allows you to de ne a custom type. And
classes are just syntactic sugar over the constructor functions with some enhancements.

The following example de nes a constructor function called Person:

function Person( rstName, lastName) {


this. rstName = rstName;
this.lastName = lastName;
}

In this example, the Person is the same as a regular function except that its name starts with the
capital letter P.

To create a new instance of the Person, you use the new operator:

let person = new Person('John','Doe');


fi
fi
fi
fi
fi
fi
fi
fi
Basically, the new operator does the following:

• Create a new empty object and assign it to the this variable.


• Assign the arguments 'John' and 'Doe' to the rstName and lastName properties of the object.
• Return the this value.
It’s functionally equivalent to the following:

function Person( rstName, lastName) {


// this = {};

// add properties to this


this. rstName = rstName;
this.lastName = lastName;

// return this;
}

Therefore, the following statement:

let person = new Person('John','Doe');

… returns the same result as the following statement:

let person = {
rstName: 'John',
lastName: 'Doe'
};

However, the constructor function Person allows you to create multiple similar objects. For example:

let person1 = new Person('Jane','Doe')


let person2 = new Person('James','Smith')

Adding methods to JavaScript constructor functions


An object may have methods that manipulate its data. To add a method to an object created via the
constructor function, you can use the this keyword. For example:

function Person( rstName, lastName) {


this. rstName = rstName;
this.lastName = lastName;

this.getFullName = function () {
return this. rstName + " " + this.lastName;
};
}
fi
fi
fi
fi
fi
fi
fi
fi
fi
Now, you can create a new Person object and invoke the getFullName() method:

let person = new Person("John", "Doe");


console.log(person.getFullName());

Output:

John Doe

The problem with the constructor function is that when you create multiple instances of the Person,
the this.getFullName() is duplicated in every instance, which is not memory ef cient.

To resolve this, you can use the prototype so that all instances of a custom type can share the same methods.

Returning from constructor functions


Typically, a constructor function implicitly returns this that set to the newly created object. But if it
has a return statement, then here’s are the rules:

• If return is called with an object, the constructor function returns that object instead of this.
• If return is called with a value other than an object, it is ignored.

Calling a constructor function without the new keyword


Technically, you can call a constructor function like a regular function without using the new keyword like this:

let person = Person('John','Doe');

In this case, the Person just executes like a regular function. Therefore, the this inside the Person function
doesn’t bind to the person variable but the global object.

If you attempt to access the rstName or lastName property, you’ll get an error:

console.log(person. rstName);

Error:

TypeError: Cannot read property ' rstName' of unde ned

Similarly, you cannot access the getFullName() method since it’s bound to the global object.

person.getFullName();
fi
fi
fi
fi
fi
Error:

TypeError: Cannot read property 'getFullName' of unde ned

To prevent a constructor function to be invoked without the new keyword, ES6 introduced the new.target property.

If a constructor function is called with the new keyword, the new.target returns a reference of the function.
Otherwise, it returns unde ned.

The following adds a statement inside the Person function to show the new.target to the console:

function Person( rstName, lastName) {


console.log(new.target);

this. rstName = rstName;


this.lastName = lastName;

this.getFullName = function () {
return this. rstName + " " + this.lastName;
};
}

The following returns unde ned because the Person constructor function is called like a regular function:

let person = Person("John", "Doe");

Output:

unde ned

However, the following returns a reference to the Person function because it’s called with the new keyword:

let person = new Person("John", "Doe");

Output:

[Function: Person]

By using the new.target, you can force the callers of the constructor function to use the new keyword.
Otherwise, you can throw an error like this:

function Person( rstName, lastName) {


if (!new.target) {
throw Error("Cannot be called without the new keyword");
}
this. rstName = rstName;
this.lastName = lastName;
}
fi
fi
fi
fi
fi
fi
fi
fi
fi
fi
fi
Alternatively, you can make the syntax more exible by creating a new Person object if the users of
the constructor function don’t use the new keyword:

function Person( rstName, lastName) {


if (!new.target) {
return new Person( rstName, lastName);
}

this. rstName = rstName;


this.lastName = lastName;
}

let person = Person("John", "Doe");

console.log(person. rstName);

This pattern is often used in JavaScript libraries and frameworks to make the syntax more exible.

Summary
• JavaScript constructor function is a regular function used to create multiple similar objects.
fi
fi
fi
fi
fi
fl
fl
Prototype
Summary: in this tutorial, you’ll learn about the JavaScript prototype and how it works under the hood.

Introduction to JavaScript prototype


In JavaScript, objects can inherit features from one another via prototypes. Every object has its own property
called prototype.

Because a prototype itself is also another object, the prototype has its own prototype. This creates a something
called prototype chain. The prototype chain ends when a prototype has null for its own prototype.

Suppose you have an object person with a property called name:

let person = {'name' : 'John'}

When examining the person object in the console, you’ll nd that the person object has a property
called prototype denoted by the [[Prototype]]:

The prototype itself is an object with its own properties:


fi
When you access a property of an object, if the object has that property, it’ll return the property
value. The following example accesses the name property of the person object:

It returns the value of the name property as expected.

However, if you access a property that doesn’t exist in an object, the JavaScript engine will search
in the prototype of the object.

If the JavaScript engine cannot nd the property in the object’s prototype, it’ll search in the
prototype’s prototype until either it nds the property or reaches the end of the prototype chain.

For example, you can call the toString() method of the person object like this:

The toString() method returns the string representation of the person object. By default, it’s [object
Object] which is not obvious.

Note that when a function is a value of an object’s property, it’s called a method.
Therefore, a method is a property with value as a function.

In this example, when we call the toString() method on the person object, the JavaScript
engine nds it in the person object. Because the person object doesn’t have
the toString() method, it’ll search for the toString() method in the person’s prototype object.
Since the person’s prototype has the toString() method, JavaScript calls the toString() of the
person’s prototype object.
fi
fi
fi
JavaScript prototype illustration
JavaScript has the built-in Object() function. The typeof operator returns 'function' if you pass
the Object function to it. For example:

typeof(Object)

Output:

'function'

Please note that Object() is a function, not an object. It’s confusing if this is the rst time you’ve
learned about the JavaScript prototype.

Also, JavaScript provides an anonymous object that can be referenced via the prototype property
of the Object() function:

console.log(Object.prototype);

The Object.prototype object has some useful properties and methods such as toString() and valueOf().

The Object.prototype also has an important property called constructor that references the Object() function.

The following statement con rms that the Object.prototype.constructor property references the Object function:

console.log(Object.prototype.constructor === Object); // true

Suppose a circle represents a function and a square represents an object. The following picture illustrates
the relationship between the Object() function and the Object.prototype object:
fi
fi
First, de ne a constructor function called Person as follows:

function Person(name) {
this.name = name;
}

In this example, the Person() function accepts a name argument and assigns it to the name property of
the this object.

Behind the scenes, JavaScript creates a new function Person() and an anonymous object:

Like the Object() function, the Person() function has a property called prototype that references an anonymous
object. And the anonymous object has the constructor property that references the Person() function.

The following shows the Person() function and the anonymous object referenced by the Person.prototype:

console.log(Person);
console.log(Person.prototype);
fi
In addition, JavaScript links the Person.prototype object to the Object.prototype object via the [[Prototype]],
which is known as a prototype linkage.

The prototype linkage is denoted by [[Prototype]] in the following gure:

De ning methods in the JavaScript prototype object


The following de nes a new method called greet() in the Person.prototype object:

Person.prototype.greet = function() {
return "Hi, I'm " + this.name + "!";
}

In this case, the JavaScript engine adds the greet() method to the Person.prototype object:
fi
fi
fi
The following creates a new instance of the Person :

let p1 = new Person('John');

Internally, the JavaScript engine creates a new object named p1 and links the p1 object to
the Person.prototype object via the prototype linkage:

The link between p1, Person.prototype, and Object.protoype is called a prototype chain.

The following calls the greet() method on the p1 object:

let greeting = p1.greet();


console.log(greeting);

Because p1 doesn’t have the greet() method, JavaScript follows the prototype linkage and nds it on the Person.prototype object.

Since JavaScript can nd the greet() method on the Person.prototype object, it executes the greet() method and returns the result:

The following calls the toString() method on the p1 object:

let s = p1.toString();
console.log(s);

In this case, the JavaScript engine follows the prototype chain to look up for the toString() method in
the Person.prototype.

Because the Person.prototype doesn’t have the toString() method, the JavaScript engine goes up to the
prototype chain and searches for the toString() method in the Object.prototype object.

Since JavaScript can nd the toString() method in the Object.prototype, it executes the toString() method.
fi
fi
fi
If you call a method that doesn’t exist on the Person.prototype and Object.prototype object, the JavaScript
engine will follow the prototype chain and throw an error if it cannot nd the method. For example:

p1. y();

Because the y() method doesn’t exist on any object in the prototype chain, the JavaScript engine
issues the following error:

TypeError: p1. y is not a function

The following creates another instance of the Person whose name property is ‘Jane':

let p2 = new Person('Jane');


fl
fl
fl
fi
The p2 object has the properties and methods as the p1 object.

In conclusion, when you de ne a method on the prototype object, this method is shared by all instances.

De ning methods in an individual object


The following de nes the draw() method on the p2 object.

p2.draw = function () {
return "I can draw.";
};

The JavaScript engine adds the draw() method to the p2 object, not the Person.prototype object:

It means that you can call the draw() method on the p2 object:

p2.draw();

But you cannot call the draw() method on the p1 object:

p1.draw()

Error:

TypeError: p1.draw is not a function

When you de ne a method in an object, the method is only available to that object. It cannot
be shared with other objects by default.
fi
fi
fi
fi
Getting prototype linkage
The __proto__ is pronounced as dunder proto. The __proto__ is an accessor property of
the Object.prototype object. It exposes the internal prototype linkage ( [[Prototype]]) of an object
through which it is accessed.

The __proto__ has been standardized in ES6 to ensure compatibility for web browsers. However, it
may be deprecated in favor of Object.getPrototypeOf() in the future. Therefore, you should never
use the __proto__ in your production code.

The p1.__proto__ exposes the [[Prototype]] that references the Person.prototype object.

Similarly, p2.__proto__ also references the same object as p1.__proto__:

console.log(p1.__proto__ === Person.prototype); // true


console.log(p1.__proto__ === p2.__proto__); // true

As mentioned earlier, you should use the Object.getPrototypeOf() method instead of the __proto__.
The Object.getPrototypeOf() method returns the prototype of a speci ed object.

console.log(p1.__proto__ === Object.getPrototypeOf(p1)); // true

Another popular way to get the prototype linkage is when the Object.getPrototypeOf() method is not
available is via the constructor property as follows:

p1.constructor.prototype

The p1.constructor returns Person, therefore, p1.constructor.prototype returns the prototype object.

Shadowing
See the following method call:

console.log(p1.greet());

The p1 object doesn’t have the greet() method de ned, therefore JavaScript goes up to the prototype chain to nd
it. In this case, it can nd the method in the Person.prototype object.

Let’s add a new method to the object p1 with the same name as the method in the Person.prototype object:

p1.greet = function() {
console.log('Hello');
}
fi
fi
fi
fi
And call the greet() method:

console.log(p1.greet());

Because the p1 object has the greet() method, JavaScript just executes it immediately without looking it up
in the prototype chain.

This is an example of shadowing. The greet() method of the p1 object shadows the greet() method of
the prototype object which the p1 object references.

Summary
• The Object() function has a property called prototype that references a Object.prototype object.
• The Object.prototype object has all properties and methods which are available in all objects such
as toString() and valueOf().
• The Object.prototype object has the constructor property that references the Object function.
• Every function has a prototype object. This prototype object references the Object.prototype object
via [[prototype]] linkage or __proto__ property.
• The prototype chain allows one object to use the methods and properties of its prototype objects via
the [[prototype]] linkages.
• The Object.getPrototypeOf() method returns the prototype object of a given object. Do use
the Object.getPrototypeOf() method instead of __proto__.
Constructor/Prototype pattern
Summary: in this tutorial, you’ll learn how to use the JavaScript constructor/Prototype pattern
to de ne a custom type in ES5.

Introduction to the JavaScript Constructor / Prototype pattern


The combination of the constructor and prototype patterns is the most common way to de ne
custom types in ES5. In this pattern:

• The constructor pattern de nes the object properties.


• The prototype pattern de nes the object methods.
By using this pattern, all objects of the custom type share the methods de ned in the prototype.
Also, each object has its own properties.

This constructor/prototype pattern takes the best parts of both constructor and prototype patterns.

JavaScript Constructor / Prototype example


Suppose that you want to de ne a custom type called Person that has:

• Two properties rstName and lastName


• One method getFullName()
First, use the constructor function to initialize the properties:

function Person( rstName, lastName) {


this. rstName = rstName;
this.lastName = lastName;
}

Behind the scene, the JavaScript engine de nes a Person function denoted by the circle and an anonymous object
denoted by the square.

The Person function has the prototype property that references an anonymous object. The anonymous object has
a constructor property that references the Person function:
fi
fi
fi
fi
fi
fi
fi
fi
fi
fi
fi
Second, de ne the getFullName() method in the prototype object of the Person function:

Person.prototype.getFullName = function () {
return this. rstName + ' ' + this.lastName;
};

JavaScript de nes the getFullName() method on the Person.prototype object like this:

Third, create multiple instances of the Person type:

let p1 = new Person("John", "Doe");


let p2 = new Person("Jane", "Doe");

console.log(p1.getFullName());
console.log(p2.getFullName());

Output:

'John Doe'
'Jane Doe'

Javascript creates two objects p1 and p2. These objects link to the Person.prototype object via
the [[Prototype]] linkage:
fi
fi
fi
Each object has its own properties rstName and lastName. However, they share the same getFullName() method.

When you call the getFullName() method on the p1 or p2 object, the JavaScript engine searches for the method on these
objects. Because the JavaScript engine doesn’t nd the method there, it follows the prototype linkage and searches for the
method in the Person.prototype object.

Because the Person.prototype object has the getFullName() method, JavaScript stops searching and executes the method.

Put it all together:

function Person( rstName, lastName) {


this. rstName = rstName;
this.lastName = lastName;
}

Person.prototype.getFullName = function () {
return this. rstName + ' ' + this.lastName;
};

let p1 = new Person('John', 'Doe');


let p2 = new Person('Jane', 'Doe');

console.log(p1.getFullName());
console.log(p2.getFullName());
fi
fi
fi
fi
fi
fi
Classes in ES6
ES6 introduces the class keyword that makes the constructor/prototype pattern easier to use.
For example, the following uses the class keyword to de ne exactly the same Person type:

class Person {
constructor( rstName, lastName) {
this. rstName = rstName;
this.lastName = lastName;
}
getFullName() {
return this. rstName + " " + this.lastName;
}
}

let p1 = new Person('John', 'Doe');


let p2 = new Person('Jane', 'Doe');

console.log(p1.getFullName());
console.log(p2.getFullName());

In this syntax, the class moves the property initialization to the constructor method. It also packs
the getFullName() method in the same place as the constructor function.

The class syntax looks cleaner and less verbose. However, it’s syntactic sugar over the constructor/
prototype pattern with some enhancements.

Summary
• Use JavaScript constructor/prototype to de ne a custom type in ES5.
• Initialize the object properties in the constructor function and de ne methods and
properties that can be shared by all instances in the prototype object.
fi
fi
fi
fi
fi
fi
fi
Prototypal inheritance
Summary: in this tutorial, you’ll learn how the JavaScript prototypal inheritance works.

Introduction to JavaScript prototypal inheritance


If you’ve worked with other object-oriented programming languages such as Java or C++, you’ve been
familiar with the inheritance concept.

In this programming paradigm, a class is a blueprint for creating objects. If you want a new class to reuse
the functionality of an existing class, you can create a new class that extends the existing class. This is
called classical inheritance.

JavaScript doesn’t use classical inheritance. Instead, it uses prototypal inheritance.

In prototypal inheritance, an object “inherits” properties from another object via the prototype linkage.

JavaScript prototypal inheritance and __proto__


Let’s take an example to make the concept clear.
The following de nes a person object:

let person = {
name: "John Doe",
greet: function () {
return "Hi, I'm " + this.name;
}
};

In this example, the person object has a property and a method:

• name is a property that stores the person’s name.


• greet is a method that returns a greeting as a string.
By default, the JavaScript engine provides you with a built-in Object() function and an anonymous
object that can be referenced by the Object.prototype:
fi
Note that the circle represents a function while the square represents an object.

The person object has a link to the anonymous object referenced by the Object() function.
The [[Prototype]] represents the linkage:

It means that the person object can call any methods de ned in the anonymous object referenced
by the Object.prototype likes this. For example, the following shows how to call the toString() method
via the person object:

console.log(person.toString());

Output:

[object Object]

The [object Object] is the default string representation of an object.

When you call toString() method via person, the JavaScript engine cannot nd it on
the person object. Therefore, the JavaScript engine follows the prototype chain and searches for
the method in the Object.prototype object.

Since the JavaScript engine can nd the toString() method in the Object.prototype object, it
executes the toString() method.

To access the prototype of the person object, you can use the __proto__ property as follows

console.log(person.__proto__);

The following shows the person.__proto__ and Object.prototype references the same object:

console.log(person.__proto__ === Object.prototype); // true


fi
fi
fi
The following de nes the teacher object that has the teach() method:

let teacher = {
teach: function (subject) {
return "I can teach " + subject;
}
};

Like the person object, the teacher.__proto__ references the Object.prototype as illustrated in the following picture:

If you want the teacher object to access all methods and properties of the person object, you
can set the prototype of teacher object to the person object like this:

teacher.__proto__ = person;

Note that you should never use the __proto__ property in the production code.
Please use it for demonstration purposes only.
fi
Now, the teacher object can access the name property and greet() method from the person object via
the prototype chain:

console.log(teacher.name);
console.log(teacher.greet());

Output:

John Doe
Hi, I'm John Doe

When you call the greet() method on the teacher object, the JavaScript engine nds it in the teacher object rst.

Since the JavaScript engine cannot nd the method in the teacher object, it follows the prototype chain and
searches for the method in the person object. Because the JavaScript can engine can nd the greet() method in
the person object, it executes the method.

In JavaScript, we say that the teacher object inherits the methods and properties of the person object. And this
kind of inheritance is called prototypal inheritance.

A standard way to implement prototypal inheritance in ES5


ES5 provided a standard way to work with prototypal inheritance by using the Object.create() method.

Note that now you should use the newer ES6 class and extends keywords to
implement inheritance. It’s much simpler.

The Object.create() method creates a new object and uses an existing object as a prototype of the new object:

Object.create(proto, [propertiesObject])

The Object.create() method accepts two arguments:

• The rst argument (proto) is an object used as the prototype for the new object.
• The second argument (propertiesObject), if provided, is an optional object that de nes additional
properties for the new object.
Suppose you have a person object:

let person = {
name: "John Doe",
greet: function () {
return "Hi, I'm " + this.name;
}
};
fi
fi
fi
fi
fi
fi
The following creates an empty teacher object with the __proto__ of the person object:

let teacher = Object.create(person);

After that, you can de ne properties for the teacher object:

teacher.name = 'Jane Doe';


teacher.teach = function (subject) {
return "I can teach " + subject;
}

Or you can do all of these steps in one statement as follows:

let teacher = Object.create(person, {


name: { value: 'John Doe' } ,
teach: { value: function(subject) {
return "I can teach " + subject;
}}
});

ES5 also introduced the Object.getPrototypeOf() method that returns the prototype of an object. For example:

console.log(Object.getPrototypeOf(teacher) === person);

Output:

true

Summary
• Inheritance allows an object to use the properties and methods of another object without
duplicating the code.
• JavaScript uses the prototypal inheritance.
fi
What is this in JavaScript
Summary: in this tutorial, you will learn about the JavaScript this value and understand it
clearly in various contexts.
If you have been working with other programming languages such as Java, C#, or PHP,
you’re already familiar with the this keyword.
In these languages, the this keyword represents the current instance of the class. And it is
only relevant within the class.
JavaScript also has this keyword. However, the this keyword in JavaScript behaves
differently from other programming languages.
In JavaScript, you can use the this keyword in the global and function contexts. Moreover,
the behavior of the this keyword changes between strict and non-strict modes.

What is this keyword


In general, the this references the object of which the function is a property. In other words, the this references the
object that is currently calling the function.

Suppose you have an object called counter that has a method next(). When you call the next() method, you can
access the this object.

let counter = {
count: 0,
next: function () {
return ++this.count;
},
};

counter.next();

Inside the next() function, the this references the counter object. See the following method call:

counter.next();

The next() is a function that is the property of the counter object. Therefore, inside the next() function,
the this references the counter object.
Global context
In the global context, the this references the global object, which is the window object on the web browser
or global object on Node.js.

This behavior is consistent in both strict and non-strict modes. Here’s the output on the web browser:

console.log(this === window); // true

If you assign a property to this object in the global context, JavaScript will add the property to
the global object as shown in the following example:

this.color= 'Red';
console.log(window.color); // 'Red'

Function context
In JavaScript, you can call a function in the following ways:
• Function invocation
• Method invocation
• Constructor invocation
• Indirect invocation
Each function invocation de nes its own context. Therefore, the this behaves differently.

1) Simple function invocation


In the non-strict mode, the this references the global object when the function is called as follows:

function show() {
console.log(this === window); // true
}

show();

When you call the show() function, the this references the global object, which is the window on the
web browser and global on Node.js.

Calling the show() function is the same as:

window.show();
fi
In the strict mode, JavaScript sets the this inside a function to unde ned. For example:

"use strict";

function show() {
console.log(this === unde ned);
}

show();

To enable the strict mode, you use the directive "use strict" at the beginning of the JavaScript le. If you
want to apply the strict mode to a speci c function only, you place it at the top of the function body.

Note that the strict mode has been available since ECMAScript 5.1. The strict mode applies to both
function and nested functions. For example:

function show() {
"use strict";
console.log(this === unde ned); // true

function display() {
console.log(this === unde ned); // true
}
display();
}

show();

Output:

true
true

In the display() inner function, the this also set to unde ned as shown in the console.
fi
fi
fi
fi
fi
fi
fi
2) Method invocation
When you call a method of an object, JavaScript sets this to the object that owns the method. See
the following car object:

let car = {
brand: 'Honda',
getBrand: function () {
return this.brand;
}
}

console.log(car.getBrand()); // Honda

In this example, the this object in the getBrand() method references the car object.
Since a method is a property of an object which is a value, you can store it in a variable.

let brand = car.getBrand;

And then call the method via the variable

console.log(brand()); // unde ned

You get unde ned instead of "Honda" because when you call a method without specifying its
object, JavaScript sets this to the global object in non-strict mode and unde ned in the strict mode.

To x this issue, you use the bind() method of the Function.prototype object. The bind() method
creates a new function whose the this keyword is set to a speci ed value.

let brand = car.getBrand.bind(car);


console.log(brand()); // Honda

In this example, when you call the brand() method, the this keyword is bound to the car object. For example:

let car = {
brand: 'Honda',
getBrand: function () {
return this.brand;
}
}

let bike = {
brand: 'Harley Davidson'
}

let brand = car.getBrand.bind(bike);


console.log(brand());
fi
fi
fi
fi
fi
Output:

Harley Davidson

In this example, the bind() method sets the this to the bike object, therefore, you see the value of
the brand property of the bike object on the console.

3) Constructor invocation
When you use the new keyword to create an instance of a function object, you use the function as a constructor.

The following example declares a Car function, then invokes it as a constructor:

function Car(brand) {
this.brand = brand;
}

Car.prototype.getBrand = function () {
return this.brand;
}

let car = new Car('Honda');


console.log(car.getBrand());

The expression new Car('Honda') is a constructor invocation of the Car function.

JavaScript creates a new object and sets this to the newly created object. This pattern works great with
only one potential problem.

Now, you can invoke the Car() as a function or as a constructor. If you omit the new keyword as follows:

var bmw = Car('BMW');


console.log(bmw.brand);
// => TypeError: Cannot read property 'brand' of unde ned

Since the this value in the Car() sets to the global object, the bmw.brand returns unde ned.

To make sure that the Car() function is always invoked using constructor invocation, you add a check at
the beginning of the Car() function as follows:

function Car(brand) {
if (!(this instanceof Car)) {
throw Error('Must use the new operator to call the function');
}
this.brand = brand;
}
fi
fi
ES6 introduced a meta-property named new.target that allows you to detect whether a function is
invoked as a simple invocation or as a constructor.

You can modify the Car() function that uses the new.target metaproperty as follows:

function Car(brand) {
if (!new.target) {
throw Error('Must use the new operator to call the function');
}
this.brand = brand;
}

4) Indirect Invocation
In JavaScript, functions are rst-class citizens. In other words, functions are objects, which are instances
of the Function type.

The Function type has two methods: call() and apply() . These methods allow you to set the this value
when calling a function. For example:

function getBrand(pre x) {
console.log(pre x + this.brand);
}

let honda = {
brand: 'Honda'
};
let audi = {
brand: 'Audi'
};

getBrand.call(honda, "It's a ");


getBrand.call(audi, "It's an ");

Output:

It's a Honda
It's an Audi

In this example, we called the getBrand() function indirectly using the call() method of the getBrand function. We
passed honda and audi object as the rst argument of the call() method, therefore, we got the corresponding
brand in each call.

The apply() method is similar to the call() method except that its second argument is an array of arguments.

getBrand.apply(honda, ["It's a "]); // "It's a Honda"


getBrand.apply(audi, ["It's an "]); // "It's a Audi"
fi
fi
fi
fi
Arrow functions
ES6 introduced a new concept called arrow function. In arrow functions, JavaScript sets the this lexically.

It means the arrow function does not create its own execution context but inherits the this from the outer
function where the arrow function is de ned. See the following example:

let getThis = () => this;


console.log(getThis() === window); // true

In this example, the this value is set to the global object i.e., window in the web browser.

Since an arrow function does not create its own execution context, de ning a method using an arrow function will
cause an issue. For example:

function Car() {
this.speed = 120;
}

Car.prototype.getSpeed = () => {
return this.speed;
};

var car = new Car();


console.log(car.getSpeed()); // 👉 unde ned

Inside the getSpeed() method, the this value reference the global object, not the Car object but the global object
doesn’t have a property called speed. Therefore, the this.speed in the getSpeed() method returns unde ned.
fi
fi
fi
fi
globalThis
Summary: in this tutorial, you’ll learn how to about the JavaScript globalThis object.

Introduction to the JavaScript globalThis object


ES2020 introduced the globalThis object that provides a standard way to access the global object across environments.

Historically, JavaScript had a global object with different names in different environments.

In web browsers, the global object is window or frames.

However, the Web Workers API doesn’t have the window object because it has no browsing context. Hence, the Web
Workers API uses self as a global object.

Node.js, on the other hand, uses the global keyword to reference the global object.

Environment Global
Web Browsers this
Web Workers self
Node.js global

If you write JavaScript code that works across environments and needs to access the global object,
you have to use different syntaxes like window, frames, self, or global.

To standardize this, ES2020 introduced the globalThis that is available across environments.

For example, the following code checks if the current environment supports the Fetch API:

const canFetch = typeof globalThis.fetch === 'function';

console.log(canFetch);

The code checks if the fetch() function is a property of the global object. In the web browsers, the globalThis is
the window object. Therefore, if you run this code on the modern web browser, the canFetch will be true.

The following code returns true on the web browser:

globalThis === window

Output:

true

Summary
• Use the globalThis object to reference the global object to make the code works across environments
Object Properties
Summary: in this tutorial, you will learn about the JavaScript object’s properties and attributes
such as con gurable, enumerable, writable, get, set, and value.

Object Property types


JavaScript speci es the characteristics of properties of objects via internal attributes surrounded by
the two pairs of square brackets, e.g., [[Enumerable]].

Objects have two types of properties: data and accessor properties.

1) Data properties
A data property contains a single location for a data value. A data property has four attributes:

• [[Con gurarable]] – determines whether a property can be rede ned or removed via delete operator.
• [[Enumerable]] – indicates if a property can be returned in the for...in loop.
• [[Writable]] – speci es that the value of a property can be changed.
• [[Value]] – contains the actual value of a property.
By default, the [[Con gurable]] , [[Enumerable]]And [[Writable]] attributes set to true for all properties
de ned directly on an object. The default value of the[[Value]] attribute is unde ned.

The following example creates a person object with two properties rstName and lastName with the
con gurable, enumerable, and writable attributes set to true. And their values are set
to 'John' and 'Doe' respectively:

let person = {
rstName: 'John',
lastName: 'Doe'
};

To change any attribute of a property, you use the Object.de neProperty() method.

The Object.de neProperty() method accepts three arguments:

• An object.
• A property name of the object.
• A property descriptor object that has four properties: con gurable, enumerable, writable, and value.
If you use the Object.de neProperty() method to de ne a property of the object, the default values
of [[Con gurable]], [[Enumerable]], and [[Writable]] are set to false unless otherwise speci ed.

The following example creates a person object with the age property:

let person = {};


person.age = 25;
fi
fi
fi
fi
fi
fi
fi
fi
fi
fi
fi
fi
fi
fi
fi
fi
fi
fi
Since the default value of the [[Con gurable]] attribute is set to true, you can remove it via the delete operator:

delete person.age;
console.log(person.age);

Output:

unde ned

The following example creates a person object and adds the ssn property to it using the Object.de neProperty() method:

'use strict';

let person = {};

Object.de neProperty(person, 'ssn', {


con gurable: false,
value: '012-38-9119'
});

delete person.ssn;

Output:

TypeError: Cannot delete property 'ssn' of #<Object>

In this example, the con gurable attribute is set to false. herefore, deleting the ssn property causes an error.

Also, once you de ne a property as non-con gurable, you cannot change it to con gurable.

If you use the Object.de neProperty() method to change any attribute other than the writable, you’ll get an error. or example:

'use strict';

let person = {};

Object.de neProperty(person, 'ssn', {


con gurable: false,
value: '012-38-9119'
});

Object.de neProperty(person, 'ssn', {


con gurable: true
});
fi
fi
fi
fi
fi
fi
fi
fi
fi
fi
fi
fi
fi
fi
Output:

TypeError: Cannot rede ne property: ssn

By default, the enumerable attribute of all the properties de ned on an object is true. t means that you can
iterate over all object properties using the for...in loop like this:

let person = {};


person.age = 25;
person.ssn = '012-38-9119';

for (let property in person) {


console.log(property);
}

Output:

age
ssn

The following makes the ssn property non-enumerable by setting the enumerable attribute to false.

let person = {};


person.age = 25;
person.ssn = '012-38-9119';

Object.de neProperty(person, 'ssn', {


enumerable: false
});

for (let prop in person) {


console.log(prop);
}

Output

age
fi
fi
fi
2) Accessor properties
Similar to data properties, accessor properties also have [[Con gurable]] and [[Enumerable]] attributes.

But the accessor properties have the [[Get]] and [[Set]] attributes instead of [[Value]] and [[Writable]].

When you read data from an accessor property, the [[Get]] function is called automatically to return a
value. The default return value of the [[Get]] function is unde ned.

If you assign a value to an accessor property, the [[Set]] function is called automatically.

To de ne an accessor property, you must use the Object.de neProperty() method. or example:

let person = {
rstName: 'John',
lastName: 'Doe'
}

Object.de neProperty(person, 'fullName', {


get: function () {
return this. rstName + ' ' + this.lastName;
},
set: function (value) {
let parts = value.split(' ');
if (parts.length == 2) {
this. rstName = parts[0];
this.lastName = parts[1];
} else {
throw 'Invalid name format';
}
}
});

console.log(person.fullName);

Output:

'John Doe'

In this example:

• First, de ne the person object that contains two properties: rstName and lastName.
• Then, add the fullName property to the person object as an accessor property.
In the fullname accessor property:

• The [[Get]] returns the full name that is the result of concatenating of rstName, space,
and lastName.
• The [[Set]] method splits the argument by the space and assigns
the rstName and lastName properties the corresponding parts of the name.
• If the full name is not in the correct format i.e., rst name, space, and last name, it will throw an error.
fi
fi
fi
fi
fi
fi
fi
fi
fi
fi
fi
fi
fi
De ne multiple properties: Object.de neProperties()
In ES5, you can de ne multiple properties in a single statement using the Object.de neProperties() method. or example:

var product = {};

Object.de neProperties(product, {
name: {
value: 'Smartphone'
},
price: {
value: 799
},
tax: {
value: 0.1
},
netPrice: {
get: function () {
return this.price * (1 + this.tax);
}
}
});

console.log('The net price of a ' + product.name + ' is ' + product.netPrice.toFixed(2) + ' USD');

Output:

The net price of a Smartphone is 878.90 USD

In this example, we de ned three data properties: name, price, and tax, and one accessor property netPrice for
the product object.
fi
fi
fi
fi
fi
fi
JavaScript object property descriptor
The Object.getOwnPropertyDescriptor() method allows you to get the descriptor object of a property.
The Object.getOwnPropertyDescriptor() method takes two arguments:

1. An object

2. A property of the object

It returns a descriptor object that describes a property. The descriptor object has four properties: con gurable,
enumerable, writable, and value.

The following example gets the descriptor object of the name property of the product object in the prior example.

let person = {
rstName: 'John',
lastName: 'Doe'
};

let descriptor = Object.getOwnPropertyDescriptor(person, ' rstName');

console.log(descriptor);

Output:

{ value: 'John',
writable: true,
enumerable: true,
con gurable: true }

Summary
• JavaScript objects have two types of properties: data properties and accessor properties.
• JavaScript uses internal attributes denoted by [[...]] to describe the characteristics of properties such
as [[Con gurable]], [[Enumerable]], [[Writable]], and [[Value]], [[Get]], and [[Set]].
• The method Object.getOwnPropertyDescriptor() return a property descriptor of a property in an object.
• A property can be de ned directly on an object or indirectly via
the Object.de neProperty() or Object.de neProperties() methods. These methods can be used to change
the attributes of a property.
fi
fi
fi
fi
fi
fi
fi
fi
for…in loop
Summary: in this tutorial, you will learn how to use the JavaScript for...in loop to iterate over the
enumerable properties of an object.

Introduction to JavaScript for...in loop


The for...in loop over the enumerable properties that are keyed by strings of an object. Note that a property can be keyed by
a string or a symbol.

A property is enumerable when its internal enumerable ag is set to true.

The enumerable ag defaults to true when a property is created via a simple assignment or via a property initializer:

object.propertyName = value;

or

let obj = {
propertyName: value,
...
};

The following shows the syntax of the for...in loop:

for(const propertyName in object) {


// ...
}

The for...in allows you to access each property and value of an object without knowing the speci c
name of the property. For example:

var person = {
rstName: 'John',
lastName: 'Doe',
ssn: '299-24-2351'
};

for(var prop in person) {


console.log(prop + ':' + person[prop]);
}
fi
fl
fl
fi
Output:

rstName:John
lastName:Doe
ssn:299-24-2351

In this example, we used the for...in loop to iterate over the properties of the person object.
We accessed the value of each property using the following syntax:

object[property];

The for...in loop & Inheritance


When you loop over the properties of an object that inherits from another object, the for...in statement goes
up in the prototype chain and enumerates over inherited properties. Consider the following example:

var decoration = {
color: 'red'
};

var circle = Object.create(decoration);


circle.radius = 10;

for(const prop in circle) {


console.log(prop);
}

Output:

radius
color

The circle object has its own prototype that references the decoration object. Therefore, the for...in loop
displays the properties of the circle object and its prototype.

If you want to enumerate only the own properties of an object, you use the hasOwnProperty() method:

for(const prop in circle) {


if(circle.hasOwnProperty(prop)) {
console.log(prop);
}
}
fi
Output:

radius

The for...in loop and Array


It’s good practice to not use the for...in to iterate over an array, especially when the order of the array elements is important.

The following example works awlessly:

const items = [10 , 20, 30];


let total = 0;

for(const item in items) {


total += items[item];
}
console.log(total);

However, someone may set a property of the built-in Array type in their libraries as follows:

Array.prototype.foo = 100;

Hence, the for...in will not work correctly. For example:

// somewhere else
Array.prototype.foo = 100;

const items = [10, 20, 30];


let total = 0;

for (var prop in items) {


console.log({ prop, value: items[prop] });
total += items[prop];
}
console.log(total);

Output:

{ prop: '0', value: 10 }


{ prop: '1', value: 20 }
{ prop: '2', value: 30 }
{ prop: 'foo', value: 100 }
160
fl
Or another example:

var arr = [];


// set the third element to 3, other elements are `unde ned`
arr[2] = 3;

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


console.log(arr[i]);
}

The output shows three elements of the array, which is correct:

unde ned
unde ned
3

However, the for...in loop ignores the rst two elements:

for (const key in arr) {


console.log(arr[key]);
}

Output:

The output shows only the third element, not the rst two elements.

Summary
• The for...in loop iterates over the enumerable properties of an object. It also goes up to the prototype chain
and enumerates inherited properties.
• Avoid using for...in loop to iterate over elements of an array, especially when the index order is important.
fi
fi
fi
fi
fi
Enumerable Properties
Summary:
• A property is enumerable if it has the enumerable attribute sets to true.
The obj.propertyIsEnumerable() determines whether or not a property is enumerable.
• A property created via a simple assignment or a property initializer is enumerable.

Introduction to JavaScript enumerable properties


Enumerable properties are iterated using the for...in loop or Objects.keys() method.

In JavaScript, an object is an unordered list of key-value pairs. The key is usually a string or a symbol. The value
can be a value of any primitive type (string, boolean, number, unde ned, or null), an object, or a function.

The following example creates a new object using the object literal syntax:

const person = {
rstName: 'John',
lastName: 'Doe
};

The person object has two properties: rstName and lastName.

An object property has several internal attributes including value, writable, enumerable and con gurable. See
the Object properties for more details.

The enumerable attribute determines whether or not a property is accessible when the object’s properties are
enumerated using the for...in loop or Object.keys() method.

By default, all properties created via a simple assignment or via a property initializer are enumerable. For example:

const person = {
rstName: 'John',
lastName: 'Doe'
};

person.age = 25;

for (const key in person) {


console.log(key);
}

Output:

rstName
lastName
age
fi
fi
fi
fi
fi
fi
In this example:

• The rstName and lastName are enumerable properties because they are created via a property initializer.
• The age property is also enumerable because it is created via a simple assignment.
To change the internal enumerable attribute of a property, you use the Object.de neProperty() method. For example:

const person = {
rstName: 'John',
lastName: 'Doe'
};

person.age = 25;

Object.de neProperty(person, 'ssn', {


enumerable: false,
value: '123-456-7890'
});

for (const key in person) {


console.log(key);
}

Output:

rstName
lastName
age

In this example, the ssn property is created with the enumerable ag sets to false, therefore it does not
show up in the for...in loop.

ES6 provides a method propertyIsEnumerable() that determines whether or not a property is enumerable.
It returns true if the property is enumerable; otherwise false. For example

const person = {
rstName: 'John',
lastName: 'Doe'
};

person.age = 25;

Object.de neProperty(person, 'ssn', {


enumerable: false,
value: '123-456-7890'
});

console.log(person.propertyIsEnumerable(' rstName')); // => true


console.log(person.propertyIsEnumerable('lastName')); // => true
console.log(person.propertyIsEnumerable('age')); // => true
console.log(person.propertyIsEnumerable('ssn')); // => false
fi
fi
fi
fi
fi
fi
fi
fl
fi
Own Properties
Summary: in this tutorial, you will learn about the own properties of an object in JavaScript.
In JavaScript, an object is a collection of properties, where each property a key-value pair.
This example creates a new object called person using an object initializer:

const person = {
rstName: 'John',
lastName: 'Doe'
};

The person object has two properties: rstName and lastName.

JavaScript uses prototypal inheritance. Therefore, a property of an object can be either own or inherited.

A property that is de ned directly on an object is own while a property that the object receives from its
prototype is inherited.

The following creates an object called employee that inherits from the person object:

const employee = Object.create(person, {


job: {
value: 'JS Developer',
enumerable: true
}
});

The employee object has its own property job, and inherits rstName and lastName properties from its prototype person.

The hasOwnProperty() method returns true if a property is own. For example:

console.log(employee.hasOwnProperty('job')); // => true


console.log(employee.hasOwnProperty(' rstName')); // => false
console.log(employee.hasOwnProperty('lastName')); // => false
console.log(employee.hasOwnProperty('ssn')); // => false

Summary
• A property that is directly de ned on an object is an own property.
• The obj.hasOwnProperty() method determines whether or not a property is own.
fi
fi
fi
fi
fi
fi
Factory functions
Summary: in this tutorial, you will learn about the JavaScript factory functions which are
functions that return objects.

Introduction to the factory functions in JavaScript


A factory function is a function that returns a new object. The following creates a person object named person1:

let person1 = {
rstName: 'John',
lastName: 'Doe',
getFullName() {
return this. rstName + ' ' + this.lastName;
},
};

console.log(person1.getFullName());

Output:

John Doe

The person1 object has two properties: rstName and lastName, and one method getFullName() that returns the full name.

Suppose that you need to create another similar object called person2, you can duplicate the code as follows:

let person2 = {
rstName: 'Jane',
lastName: 'Doe',
getFullName() {
return this. rstName + ' ' + this.lastName;
},
};

console.log(person2.getFullName());

Output:

Jane Doe
fi
fi
fi
fi
fi
In this example, the person1 and person2 objects have the same properties and methods.

The problem is that the more objects you want to create, the more duplicate code you have.

To avoid copying the same code all over again, you can de ne a function that creates the person object:

function createPerson( rstName, lastName) {


return {
rstName: rstName,
lastName: lastName,
getFullName() {
return rstName + ' ' + lastName;
},
};
}

When a function creates and returns a new object, it is called a factory function. The createPerson() is a factory
function because it returns a new person object.

The following show how to use the createPerson() factory function to create two objects person1 and person2:

function createPerson( rstName, lastName) {


return {
rstName: rstName,
lastName: lastName,
getFullName() {
return rstName + ' ' + lastName;
},
};
}

let person1 = createPerson('John', 'Doe');


let person2 = createPerson('Jane', 'Doe');

console.log(person1.getFullName());
console.log(person2.getFullName());

By using the factory function, you create any number of the person objects without duplicating code.

When you create an object, the JavaScript engine allocates memory to it. If you create many person objects, the JavaScript
engine needs lots of memory spaces to store these objects.

However, each person object has a copy of the same getFullName() method. It’s not ef cient memory management.

To avoid duplicating the same getFullName() function in every object, you can remove the getFullName() method from
the person object:

function createPerson( rstName, lastName) {


return {
rstName: rstName,
lastName: lastName
}
}
fi
fi
fi
fi
fi
fi
fi
fi
fi
fi
fi
fi
fi
And move this method to another object:

var personActions = {
getFullName() {
return this. rstName + ' ' + this.lastName;
},
};

And before calling the getFullName() method on the person object, you can assign the method of
the personActions object to the person object as follows:

let person1 = createPerson('John', 'Doe');


let person2 = createPerson('Jane', 'Doe');

person1.getFullName = personActions.getFullName;
person2.getFullName = personActions.getFullName;

console.log(person1.getFullName());
console.log(person2.getFullName());

This approach is not scalable if the object has many methods because you have to manually
assign them individually. This is why the Object.create() method comes into play.

The Object.create() method


The Object.create() method creates a new object using an existing object as the prototype of the new object:

Object.create(proto, [propertiesObject])

So you can use the Object.create() as follows:

var personActions = {
getFullName() {
return this. rstName + ' ' + this.lastName;
},
};

function createPerson( rstName, lastName) {


let person = Object.create(personActions);
person. rstName = rstName;
person.lastName = lastName;
return person;
}
fi
fi
fi
fi
fi
Now, you can create person objects and call the methods of the personActions object:

let person1 = createPerson('John', 'Doe');


let person2 = createPerson('Jane', 'Doe');

console.log(person1.getFullName());
console.log(person2.getFullName());

The code works perfectly ne. However, in practice, you will rarely use the factory functions.
Instead, you use classes or constructor/prototype patterns.

Summary
• A factory function is a function that returns a new object.
• Use Object.create() to create an object using an existing object as a prototype.
fi
Section 5. Advanced Functions

call()
Summary: in this tutorial, you will learn about the JavaScript call() method and how to use it more effectively.

Introduction to the JavaScript call() method


In JavaScript, a function is an instance of the Function type. For example:

function add(x, y) {
return x + y;
}

console.log(add instanceof Function); // true

The Function.prototype type has the call() method with the following syntax:

functionName.call(thisArg, arg1, arg2, ...);

In this syntax, the call() method calls a function functionName with the arguments (arg1, arg2, …)
and the this set to thisArg object inside the function.

• The thisArg is the object that the this object references inside the function functionName.
• The arg1, arg2, .. are the function arguments passed into the functionName.
The call() method returns the result of calling the functionName().

The following example de nes the add() function and calls it normally:

function add(x, y) {
return x + y;
}

let result = add(10, 20);


console.log(result); // 30

The following calls the add() function but use the call() method instead:

function add(x, y) {
return x + y;
}

let result = add.call(this, 10, 20);


console.log(result); // 30
fi
By default, the this inside the function is set to the global object i.e., window in the web browsers
and global in Node.js.

Note that in the strict mode, the this inside the function is set to unde ned instead of the global object.

Consider the following example:

var greeting = 'Hi';

var messenger = {
greeting: 'Hello'
}

function say(name) {
console.log(this.greeting + ' ' + name);
}

Inside the say() function, we reference the greeting via the this value. If you just invoke the say() function via
the call() method as follows:

say.call(this,'John');

It’ll show the following output to the console:

"Hi John"

However, when you invoke the call() method of say function object and pass the messenger object as
the this value:

say.call(messenger,'John');

The output will be:

"Hello John"

In this case, the this value inside the say() function references the messenger object, not the global object.
fi
Using the JavaScript call() method to chain constructors for an object
You can use the call() method for chaining constructors of an object. Consider the following example:

function Box(height, width) {


this.height = height;
this.width = width;
}

function Widget(height, width, color) {


Box.call(this, height, width);
this.color = color;
}

let widget = new Widget('red', 100, 200);

console.log(widget);

Output:

Widget { height: 'red', width: 100, color: 200 }

In this example:

• First, initialize the Box object with two properties: height and width.
• Second, invoke the call() method of the Box object inside the Widget object, set the this value
to the Widget object.
Using the JavaScript call() method for function borrowing
The following example illustrates how to use the call() method for borrowing functions:

const car = {
name: 'car',
start() {
console.log('Start the ' + this.name);
},
speedUp() {
console.log('Speed up the ' + this.name);
},
stop() {
console.log('Stop the ' + this.name);
},
};

const aircraft = {
name: 'aircraft',
y() {
console.log('Fly');
},
};

car.start.call(aircraft);
car.speedUp.call(aircraft);
aircraft. y();

Output:

Start the aircraft


Speed up the aircraft
Fly

How it works.
First, de ne a car object with one property name and three methods start, speedUp, and stop:

const car = {
name: 'car',
start() {
console.log('Start the ' + this.name);
},
speedUp() {
console.log('Speed up the ' + this.name);
},
stop() {
console.log('Stop the ' + this.name);
},
};
fl
fl
fi
Second, de ne the aircraft object with one property name and a method:

const aircraft = {
name: 'aircraft',
y() {
console.log('Fly');
},
};

Third, call the start() and speedUp() method of the car object and the y() method of the aircraft object.
However, passing the aircraft as the rst argument into the start() and speedUp() methods:

car.start.call(aircraft);
car.speedUp.call(aircraft);
aircraft. y();

Inside the start() and speedUp() methods, the this references the aircraft object, not the car object.
Therefore, the this.name returns the 'aircraf' string. Hence, the methods output the following message:

Start the aircraft


Speed up the aircraft

Technically, the aircraft object borrows the start() and speedUp() method of the car object. And function borrowing
refers to an object that uses a method of another object.

The following example illustrates how the arguments object borrows the lter() method of the Array.prototype via
the call() function:

function isOdd(number) {
return number % 2;
}

function getOddNumbers() {
return Array.prototype. lter.call(arguments, isOdd);
}

let results = getOddNumbers(10, 1, 3, 4, 8, 9);


console.log(results);

Output:

[ 1, 3, 9 ]
fl
fl
fi
fi
fi
fi
fl
How it works.
First, de ne the isOdd() function that returns true if the number is an odd number:

function isOdd(number) {
return number % 2;
}

Second, de ne the getOddNumbers() function that accepts any number of arguments and returns an
array that contains only odd numbers:

function getOddNumbers() {
return Array.prototype. lter.call(arguments, isOdd);
}

In this example, the arguments object borrows the lter() method of the Array.prototype object.

Third, call the getOddNumbers() function:

let results = getOddNumbers(10, 1, 3, 4, 8, 9);


console.log(results);

In this tutorial, you have learned about the JavaScript call() method and how to use it more effectively.
fi
fi
fi
fi
apply()
Summary:
• The apply() method invokes a function with a given this value and arguments provided as an array.
• The apply() method is similar to the call() method excepts that it accepts the arguments of the
function as an array instead of individual arguments.

Introduction to the JavaScript apply() method


The Function.prototype.apply() method allows you to call a function with a given this value and
arguments provided as an array. Here is the syntax of the apply() method:

fn.apply(thisArg, [args]);

The apply() method accepts two arguments:

• The thisArg is the value of this provided for the call to the function fn.
• The args argument is an array that speci es the arguments of the function fn. Since the ES5,
the args argument can be an array-like object or array object.
The apply() method is similar to the call() method except that it takes the arguments of the function
as an array instead of the individual arguments.

JavaScript apply() method examples


Let’s take some examples of using the apply() method.

1) Simple JavaScript apply() method example


Suppose that you have a person object:

const person = {
rstName: 'John',
lastName: 'Doe'
}

…and a function named greet() as follows:

function greet(greeting, message) {


return `${greeting} ${this. rstName}. ${message}`;
}
fi
fi
fi
The greet() function accepts two parameters: greeting and message. Inside the greet() function, we reference an
object that has the rstName property.

The following example shows how to use the apply() method to call the greet() function with the this set to
the person object:

let result = greet.apply(person, ['Hello', 'How are you?']);

console.log(result);

Output:

Hello John. How are you?

In this example, we set the this value inside the function to the person object. The arguments of
the greet() function was passed into the apply() method as an array.

The apply() method invoked the greet() function with the this value set to the person object and arguments
as an array ['Hello', 'How are you?'].

If you use the call() method, you need to pass the arguments of the greet() function separately as follows:

let result = greet.call(person, Hello', 'How are you?');

2) Function borrowing
The apply() method allows an object to borrow the method of another object without duplicating the code.

Suppose that you have the following computer object:

const computer = {
name: 'MacBook',
isOn: false,
turnOn() {
this.isOn = true;
return `The ${this.name} is On`;
},
turnO () {
this.isOn = false;
return `The ${this.name} is O `;
}
};
ff
fi
ff
… and the following server object:

const server = {
name: 'Dell PowerEdge T30',
isOn: false
};

The server object doesn’t have the turnOn() and turnOff() methods.

To execute the turnOn() method of the computer object on the server object, you can use the apply() method as follows:

let result = computer.turnOn.apply(server);

console.log(result);

Output:

The Dell PowerEdge T30 is On

In this example, the server object borrows the turnOn() method of the computer object.
Similarly, you can call the turnOff() method of the computer object on the server object:

let result = computer.turnO .apply(server);


console.log(result);

Output:

The Dell PowerEdge T30 is O

3) Using the apply() method to append an array to another


The apply() method allows you to append elements of an array to another:

let arr = [1, 2, 3];


let numbers = [4, 5, 6];
arr.push.apply(arr, numbers);
console.log(arr);

In this example, the apply() method modi es the original array arr. Note that the Array.prototype.concat() method also
provides the same result except that it returns the new array instead of modifying the original array.
ff
f
fi
bind()
Summary: in this tutorial, you will learn about the JavaScript bind() method and know how to use it effectively.

Introduction to JavaScript bind() method


The bind() method returns a new function, when invoked, has its this sets to a speci c value.
The following illustrates the syntax of the bind() method:

fn.bind(thisArg[, arg1[, arg2[, ...]]])

In this syntax, the bind() method returns a copy of the function fn with the speci c this value
(thisArg) and arguments (arg1, arg2, …).

Unlike the call() and apply() methods, the bind() method doesn’t immediately execute the
function. It just returns a new version of the function whose this sets to thisArg argument.

Using JavaScript bind() for function binding


When you pass a method an object is to another function as a callback, the this is lost. For example:

let person = {
name: 'John Doe',
getName: function() {
console.log(this.name);
}
};

setTimeout(person.getName, 1000);

Output:

unde ned

As you can see clearly from the output, the person.getName() returns unde ned instead of 'John Doe'.

This is because setTimeout() received the function person.getName separately from the person object.

The statement:

setTimeout(person.getName, 1000);
fi
fi
fi
fi
can be rewritten as:

let f = person.getName;
setTimeout(f, 1000); // lost person context

The this inside the setTimeout() function is set to the global object in non-strict mode and unde ned in the
strict mode.

Therefore, when the callback person.getName is invoked, the name does not exist in the global object, it is
set to unde ned.

To x the issue, you can wrap the call to the person.getName method in an anonymous function, like this:

setTimeout(function () {
person.getName();
}, 1000);

This works because it gets the person from the outer scope and then calls the method getName().

Or you can use the bind() method:

let f = person.getName.bind(person);
setTimeout(f, 1000);

In this code:

• First, bind the person.getName method to the person object.


• Second, pass the bound function f with this value set to the person object to the setTimeout() function.

Using bind() to borrow methods from a different object


Suppose you have a runner object that has the run() method:

let runner = {
name: 'Runner',
run: function(speed) {
console.log(this.name + ' runs at ' + speed + ' mph.');
}
};

And the yer object that has the y() method:

let yer = {
name: 'Flyer',
y: function(speed) {
console.log(this.name + ' ies at ' + speed + ' mph.');
}
};
fl
fi
fl
fl
fi
fl
fl
fi
If you want the yer object to be able to run, you can use the bind() method to create the run() function
with the this sets to the yer object:

let run = runner.run.bind( yer, 20);


run();

In this statement:
• Call the bind() method of the runner.run() method and pass in the yer object as the rst
argument and 20 as the second argument.
• Invoke the run() function.
Output:

Flyer runs at 20 mph.

The ability to borrow a method of an object without making a copy of that method and
maintain it in two separate places is very powerful in JavaScript.

Summary
• The bind() method creates a new function, when invoked, has the this sets to a provided value.
• The bind() method allows an object to borrow a method from another object without making a copy
of that method. This is known as function borrowing in JavaScript.
fl
fl
fl
fl
fi
Closure
Summary: in this tutorial, you will learn about JavaScript closures and how to use closures in
your code more effectively.

Introduction to JavaScript closures


In JavaScript, a closure is a function that references variables in the outer scope from its
inner scope. The closure preserves the outer scope inside its inner scope.
To understand the closures, you need to know how the lexical scoping works rst.

Lexical scoping
Lexical scoping de nes the scope of a variable by the position of that variable declared in the
source code. For example:

let name = 'John';

function greeting() {
let message = 'Hi';
console.log(message + ' '+ name);
}

In this example:

• The variable name is a global variable. It is accessible from anywhere including within the greeting() function.
• The variable message is a local variable that is accessible only within the greeting() function.
If you try to access the message variable outside the greeting() function, you will get an error.

So the JavaScript engine uses the scope to manage the variable accessibility.

According to lexical scoping, the scopes can be nested and the inner function can access the variables declared in its outer
scope. For example:

function greeting() {
let message = 'Hi';

function sayHi() {
console.log(message);
}

sayHi();
}

greeting();
fi
fi
The greeting() function creates a local variable named message and a function named sayHi().

The sayHi() is the inner function that is available only within the body of the greeting() function.

The sayHi() function can access the variables of the outer function such as the message variable of the greeting() function.

Inside the greeting() function, we call the sayHi() function to display the message Hi.

JavaScript closures
Let’s modify the greeting() function:

function greeting() {
let message = 'Hi';

function sayHi() {
console.log(message);
}

return sayHi;
}
let hi = greeting();
hi(); // still can access the message variable

Now, instead of executing the sayHi() function inside the greeting() function, the greeting() function returns
the sayHi() function object.

Note that functions are the rst-class citizens in JavaScript, therefore, you can return a function from
another function.

Outside of the greeting() function, we assigned the hi variable the value returned by the greeting() function,
which is a reference of the sayHi() function.

Then we executed the sayHi() function using the reference of that function: hi(). If you run the code, you
will get the same effect as the one above.

However, the interesting point here is that, normally, a local variable only exists during the execution of the
function.

It means that when the greeting() function has completed executing, the message variable is no longer
accessible.

In this case, we execute the hi() function that references the sayHi() function, the message variable still
exists.

The magic of this is closure. In other words, the sayHi() function is a closure.

A closure is a function that preserves the outer scope in its inner scope.
fi
More JavaScript Closure example
The following example illustrates a more practical example of closure.

function greeting(message) {
return function(name){
return message + ' ' + name;
}
}
let sayHi = greeting('Hi');
let sayHello = greeting('Hello');

console.log(sayHi('John')); // Hi John
console.log(sayHello('John')); // Hello John

The greeting() function takes one argument named message and returns a function that accepts a single argument
called name.

The return function returns a greeting message that is the combination of the message and name variables.

The greeting() function behaves like a function factory. It creates sayHi() and sayHello() functions with the
respective messages Hi and Hello.

The sayHi() and sayHello() are closures. They share the same function body but store different scopes.

In the sayHi() closure, the message is Hi, while in the sayHello() closure the message is Hello.

JavaScript closures in a loop


Consider the following example:

for (var index = 1; index <= 3; index++) {


setTimeout(function () {
console.log('after ' + index + ' second(s):' + index);
}, index * 1000);
}

Output

after 4 second(s):4
after 4 second(s):4
after 4 second(s):4
The code shows the same message.

What we wanted to do in the loop is to copy the value of i in each iteration at the time of iteration to
display a message after 1, 2, and 3 seconds.

The reason you see the same message after 4 seconds is that the callback passed to
the setTimeout() a closure. It remembers the value of i from the last iteration of the loop, which is 4.

In addition, all three closures created by the for-loop share the same global scope access the same
value of i.

To x this issue, you need to create a new closure scope in each iteration of the loop.

There are two popular solutions: IIFE & let keyword.

1) Using the IIFE solution


In this solution, you use an immediately invoked function expression (a.k.a IIFE) because an
IIFE creates a new scope by declaring a function and immediately execute it.

for (var index = 1; index <= 3; index++) {


(function (index) {
setTimeout(function () {
console.log('after ' + index + ' second(s):' + index);
}, index * 1000);
})(index);
}

Output

after 1 second(s):1
after 2 second(s):2
after 3 second(s):3
fi
2) Using let keyword in ES6
In ES6, you can use the let keyword to declare a variable that is block-scoped.

If you use the let keyword in the for-loop, it will create a new lexical scope in each iteration. In other
words, you will have a new index variable in each iteration.

In addition, the new lexical scope is chained up to the previous scope so that the previous value of
the index is copied from the previous scope to the new one.

for (let index = 1; index <= 3; index++) {


setTimeout(function () {
console.log('after ' + index + ' second(s):' + index);
}, index * 1000);
}

Output

after 1 second(s):1
after 2 second(s):2
after 3 second(s):3

Summary
• Lexical scoping describes how the JavaScript engine uses the location of the variable in the code to
determine where that variable is available.
• A closure is a combination of a function and its ability to remember variables in the outer scope.
Immediately Invoked Function Expression (IIFE)
Summary: in this tutorial, you will learn about JavaScript immediately invoked function
expressions (IIFE).

TL;DR
A JavaScript immediately invoked function expression is a function de ned as an expression and
executed immediately after creation. The following shows the syntax of de ning an immediately
invoked function expression:

(function(){
//...
})();

Why IIFEs
When you de ne a function, the JavaScript engine adds the function to the global object. See
the following example:

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

In web browsers, the JavaScript engine adds the add() function to the window global object:

console.log(window.add);

Likewise, if you declare a variable outside of a function using the var keyword, the JavaScript engine also
adds the variable to the global object:

var counter = 10;


console.log(window.counter); // 10

If you have many global variables and functions, the JavaScript engine will only release the memory allocated for
them until the global object loses its scopes.

As a result, the script may use the memory inef ciently. On top of that, having global variables and functions will
likely cause name collisions.

One way to prevent the functions and variables from polluting the global object is to use immediately invoked
function expressions.

In JavaScript, you can have the following expressions:

'This is a string';
(10+20);
fi
fi
fi
fi
This syntax is correct even though the expressions have no effect. A function can be also
declared as an expression which is called a function expression:

let sum = function(a, b) {


return a + b;
}

In this syntax, the part on the right side of the assignment operator(=) is a function expression.
Because a function is an expression, you can wrap it inside parentheses:

let sum = (function(a, b) {


return a + b;
});

In this example, the sum variable is referenced as the anonymous function that adds two arguments.

In addition, you can execute the function immediately after creating it:

let sum = (function(a,b){


return a + b;
})(10, 20);

console.log(sum);

In this example, the sum variable holds the result of the function call.

The following expression is called an immediately invoked function expression (IIFE) because the
function is created as an expression and executed immediately:

(function(a,b){
return a + b;
})(10,20);

This is the general syntax for de ning an IIFE:

(function(){
//...
})();

Note that you can use an arrow function to de ne an IIFE:

(() => {
//...
})();
fi
fi
By placing functions and variables inside an immediately invoked function expression, you
can avoid polluting them to the global object:

(function() {
var counter = 0;

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

console.log(add(10,20)); // 30
}());

Named IIFE
An IIFE can have a name. However, it cannot be invoked again after execution:

(function namedIIFE() {
//...
})();

IIFE starting with a semicolon (;)


Sometimes, you may see an IIFE that starts with a semicolon(;):

;(function() {
/* */
})();

In this syntax, the semicolon is used to terminate the statement in case two or more JavaScript les
are blindly concatenated into a single le.

For example, you may have two le lib1.js and lib2.js which use IIFEs:

(function(){
// ...
})()

(function(){
// ...
})()
fi
fi
fi
If you use a code bundler tool to concatenate code from both les into a single le, without
the semicolon (;) the concatenated JavaScript code will cause a syntax error.

IIFE in actions
Suppose that you have a library called calculator.js with the following functions:

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

function mutiply(a, b) {
return a * b;
}

And you load the calculator.js in an HTML document.


Later, you also want to load another JavaScript library called app.js to the same document:

<!DOCTYPE html>
<head>
<meta charset="UTF-8">
<title>JavaScript IIFE</title>
</head>
<body>
<script src="calculator.js"></script>
<script src="app.js"></script>
</body>
</html>

The app.js also has the add() function:

function add() {
return 'add';
}

When you use the add() function in the HTML document, it returns the 'add' string instead of the sum
of two numbers:

let result = add(10, 20);


console.log(result); // 'add'

This is because the add() function in the app.js overrides the add() function in the calculator.js library.
fi
fi
To x this, you can apply IIFE in the calculator.js as follows:

const calculator = (function () {


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

function multiply(a, b) {
return a * b;
}
return {
add: add,
multiply: multiply
}
})();

The IIFE returns an object that contains the add and multiply methods that reference the add() and multiply() functions. In the
HTML document, you can use the calculator.js library as follows:

<!DOCTYPE html>
<head>
<meta charset="UTF-8">
<title>JavaScript IIFE</title>
</head>
<body>
<script src="js/calculator.js"></script>
<script src="js/app.js"></script>
<script>
let result = calculator.add(10, 20); // add in app.js
console.log(result); // 30
console.log(add()); // add in the app.js
</script>
</body>
</html>

The calculator.add() called the add() function exported by the calculator.js while the second call to
the add() function references the add() function in the app.js.
fi
jQuery & IIFE
The following HTML document uses the jQuery library:

<!DOCTYPE html>
<head>
<meta charset="UTF-8">
<title>JavaScript IIFE - jQuery</title>
</head>
<body>
<h1>jQuery Demo</h1>
<script src="https://code.jquery.com/jquery-3.4.1.slim.js"
integrity="sha256-BTlTdQO9/fascB1drekrDVkaKd9PkwBymMlHOiG+qLI="
crossorigin="anonymous"></script>
<script>
let counter = 1;
$('h1').click(function () {
$(this).text('jQuery Demo' + ' Clicked ' + counter++);
});
</script>
</body>
</html>

When you import the jQuery library, you can access many useful jQuery functions via
the $ or jQuery object. Under the hood, jQuery uses the IIFE to expose its functionality.
By doing this, jQuery just needs to use one global variable ($) to expose a ton of functions
without polluting the global object.
The following example illustrates how to change the jQuery $ object to _ inside the IIFE:

(function (_) {
let counter = 1;
_('h1').click(function () {
_(this).text('jQuery Demo' + ' Clicked ' + counter++);
});
})(jQuery);

In this example, we passed the jQuery object into the IIFE and used the _ argument instead.
In this tutorial, you will have learned about the JavaScript immediately invoked function
expressions (IIFE) and their purposes.
Returning multiple values
Summary: in this tutorial, you will learn to de ne JavaScript functions that return multiple values.
JavaScript functions can return a single value. To return multiple values from a function, you
can pack the return values as elements of an array or as properties of an object.

Returning multiple values from a function using an array


Suppose the following getNames() function retrieves the rst name and last name from a database
in the backend or from the result of a third-party API call and returns them as elements of an array:

function getNames() {
// get names from the database or API
let rstName = 'John',
lastName = 'Doe';

// return as an array
return [ rstName, lastName];
}

The following shows how to get the return value from the getNames() function:

let names = getNames();

Because the names variable is an array, you can reference its elements using the square brackets, like this:

const rstName = names[0],


lastName = names[1];

In ES6, you can use the destructuring assignment syntax to unpack values from an array
more intuitively, like this:

const [ rstName, lastName] = getNames();

In this code, the rstName and lastName variables will take the rst and second elements of the return array.
fi
fi
fi
fi
fi
fi
fi
fi
Returning multiple values from an function using an object
If you want to assign a name to each returned value to make it more readable and easier to
maintain, you can use an object:

function getNames() {
// get names from the database or API
let rstName = 'John',
lastName = 'Doe';

// return values
return {
' rstName': rstName,
'lastName': lastName
};
}

Since the names of the properties are the same as the variables, you can shorten it using
the object literal syntax extensions in ES6 as follows:

function getNames() {
// get names from the database or API
let rstName = 'John',
lastName = 'Doe';

return { rstName, lastName };


}

And you can get the return value as an object like this:

let names = getNames();

let rstName = names. rstName,


lastName = names.lastName;

If you want to unpack properties from an object, you can use the object destructuring syntax as follows:

let { rstName, lastName } = getNames();

Summary
• JavaScript doesn’t support functions that return multiple values. However, you can wrap multiple
values into an array or an object and return the array or the object.
• Use destructuring assignment syntax to unpack values from the array, or properties from objects.
fi
fi
fi
fi
fi
fi
fi
fi
Callback functions
Summary: in this tutorial, you will learn about JavaScript callback functions including synchronous
and asynchronous callbacks.

What are callbacks


In JavaScript, functions are rst-class citizens. Therefore, you can pass a function to another function as an argument.

By de nition, a callback is a function that you pass into another function as an argument for executing later.

The following de nes a lter() function that accepts an array of numbers and returns a new array of odd numbers:

function lter(numbers) {
let results = [];
for (const number of numbers) {
if (number % 2 != 0) {
results.push(number);
}
}
return results;
}
let numbers = [1, 2, 4, 7, 3, 5, 6];
console.log( lter(numbers));

How it works.

• First, de ne the lter() function that accepts an array of numbers and returns a new array of the odd numbers.
• Second, de ne the numbers array that has both odd and even numbers.
• Third, call the lter() function to get the odd numbers out of the numbers array and output the result.
If you want to return an array that contains even numbers, you need to modify the lter() function. To make
the lter() function more generic and reusable, you can:

• First, extract the logic in the if block and wrap it in a separate function.
• Second, pass the function to the lter() function as an argument.
Here’s the updated code:

function isOdd(number) {
return number % 2 != 0;
}

function lter(numbers, fn) {


let results = [];
for (const number of numbers) {
if (fn(number)) {
results.push(number);
}
}
return results;
}
let numbers = [1, 2, 4, 7, 3, 5, 6];
console.log( lter(numbers, isOdd));
fi
fi
fi
fi
fi
fi
fi
fi
fi
fi
fi
fi
fi
fi
fi
The result is the same. However, you can pass any function that accepts an argument and returns
a boolean value to the second argument of the lter() function.

For example, you can use the lter() function to return an array of even numbers like this:

function isOdd(number) {
return number % 2 != 0;
}
function isEven(number) {
return number % 2 == 0;
}

function lter(numbers, fn) {


let results = [];
for (const number of numbers) {
if (fn(number)) {
results.push(number);
}
}
return results;
}
let numbers = [1, 2, 4, 7, 3, 5, 6];

console.log( lter(numbers, isOdd));


console.log( lter(numbers, isEven));

By de nition, the isOdd and isEven are callback functions or callbacks. Because the lter() function
accepts a function as an argument, it’s called a high-order function.

A callback can be an anonymous function, which is a function without a name like this:

function lter(numbers, callback) {


let results = [];
for (const number of numbers) {
if (callback(number)) {
results.push(number);
}
}
return results;
}

let numbers = [1, 2, 4, 7, 3, 5, 6];

let oddNumbers = lter(numbers, function (number) {


return number % 2 != 0;
});

console.log(oddNumbers);
fi
fi
fi
fi
fi
fi
fi
fi
fi
In this example, we pass an anonymous function to the lter() function instead of using a separate function.

In ES6, you can use an arrow function like this:

function lter(numbers, callback) {


let results = [];
for (const number of numbers) {
if (callback(number)) {
results.push(number);
}
}
return results;
}

let numbers = [1, 2, 4, 7, 3, 5, 6];

let oddNumbers = lter(numbers, (number) => number % 2 != 0);

console.log(oddNumbers);

There are two types of callbacks: synchronous and asynchronous callbacks.

Synchronous callbacks
A synchronous callback is executed during the execution of the high-order function that uses the
callback. The isOdd and isEven are examples of synchronous callbacks because they execute
during the execution of the lter() function.

Asynchronous callbacks
An asynchronous callback is executed after the execution of the high-order function that uses
the callback.
Asynchronicity means that if JavaScript has to wait for an operation to complete, it will
execute the rest of the code while waiting.
Note that JavaScript is a single-threaded programming language. It carries asynchronous
operations via the callback queue and event loop.
Suppose that you need to develop a script that downloads a picture from a remote server
and process it after the download completes:

function download(url) {
// ...
}
function process(picture) {
// ...
}
download(url);
process(picture);
fi
fi
fi
fi
However, downloading a picture from a remote server takes time depending on the network speed
and the size of the picture.

The following download() function uses the setTimeout() function to simulate the network request:

function download(url) {
setTimeout(() => {
// script to download the picture here
console.log(`Downloading ${url} ...`);
},1000);
}

And this code emulates the process() function:

function process(picture) {
console.log(`Processing ${picture}`);
}

When you execute the following code:

let url = 'https://www.javascripttutorial.net/pic.jpg';

download(url);
process(url);

you will get the following output:

Processing https://javascripttutorial.net/pic.jpg
Downloading https://javascripttutorial.net/pic.jpg ...

This is not what you expected because the process() function executes before the download() function.
The correct sequence should be:

• Download the picture and wait for the download completes.


• Process the picture.
To resolve this issue, you can pass the process() function to the download() function and execute
the process() function inside the download() function once the download completes, like this:
function download(url, callback) {
setTimeout(() => {
// script to download the picture here
console.log(`Downloading ${url} ...`);

// process the picture once it is completed


callback(url);
}, 1000);
}

function process(picture) {
console.log(`Processing ${picture}`);
}

let url = 'https://wwww.javascripttutorial.net/pic.jpg';


download(url, process);

Output:

Downloading https://www.javascripttutorial.net/pic.jpg ...


Processing https://www.javascripttutorial.net/pic.jpg

Now, it works as expected.

In this example, the process() is a callback passed into an asynchronous function.

When you use a callback to continue code execution after an asynchronous operation, the callback
is called an asynchronous callback.

To make the code more concise, you can de ne the process() function as an anonymous function:

function download(url, callback) {


setTimeout(() => {
// script to download the picture here
console.log(`Downloading ${url} ...`);
// process the picture once it is completed
callback(url);

}, 1000);
}

let url = 'https://www.javascripttutorial.net/pic.jpg';


download(url, function(picture) {
console.log(`Processing ${picture}`);
});
fi
Handling errors
The download() function assumes that everything works ne and does not consider any exceptions.
The following code introduces two callbacks: success and failure to handle the success and failure
cases respectively:

function download(url, success, failure) {


setTimeout(() => {
console.log(`Downloading the picture from ${url} ...`);
!url ? failure(url) : success(url);
}, 1000);
}

download(
'',
(url) => console.log(`Processing the picture ${url}`),
(url) => console.log(`The '${url}' is not valid`)
);

Nesting callbacks and the Pyramid of Doom


How do you download three pictures and process them sequentially? A typical approach is to call
the download() function inside the callback function, like this:

function download(url, callback) {


setTimeout(() => {
console.log(`Downloading ${url} ...`);
callback(url);
}, 1000);
}

const url1 = 'https://www.javascripttutorial.net/pic1.jpg';


const url2 = 'https://www.javascripttutorial.net/pic2.jpg';
const url3 = 'https://www.javascripttutorial.net/pic3.jpg';

download(url1, function (url) {


console.log(`Processing ${url}`);
download(url2, function (url) {
console.log(`Processing ${url}`);
download(url3, function (url) {
console.log(`Processing ${url}`);
});
});
});
fi
Output:

Downloading https://www.javascripttutorial.net/pic1.jpg ...


Processing https://www.javascripttutorial.net/pic1.jpg
Downloading https://www.javascripttutorial.net/pic2.jpg ...
Processing https://www.javascripttutorial.net/pic2.jpg
Downloading https://www.javascripttutorial.net/pic3.jpg ...
Processing https://www.javascripttutorial.net/pic3.jpg

The script works perfectly ne.


However, this callback strategy does not scale well when the complexity grows signi cantly.
Nesting many asynchronous functions inside callbacks is known as the pyramid of doom or
the callback hell:

asyncFunction(function(){
asyncFunction(function(){
asyncFunction(function(){
asyncFunction(function(){
asyncFunction(function(){
....
});
});
});
});
});

To avoid the pyramid of doom, you use promises or async/await functions.

Summary
• A callback is a function passed into another function as an argument to be executed later.
• A high-order function is a function that accepts another function as an argument.
• Callback functions can be synchronous or asynchronous.
fi
fi
Section 6. Error handling

try…catch
Summary: in this tutorial, you will learn how to use the JavaScript try...catch statement to handle exceptions.

Introduction to JavaScript try…catch statement


The following example attempts to call the add() function that doesn’t exist:

let result = add(10, 20);


console.log(result);

console.log('Bye');

And the JavaScript engine issues the following error:

Uncaught TypeError: add is not a function

The error message states that the add is not a function and the error type is TypeError.

When the JavaScript engine encounters an error, it issues that error and immediately terminates
the execution of the entire script. In the above example, the code execution stops at the rst line.

Sometimes, you want to handle the error and continue the execution. To do that, you use
the try...catch statement with the following syntax:

try {
// code may cause error
} catch(error){
// code to handle error
}

In this syntax:

• First, place the code that may cause an error in the try block.
• Second, implement the logic to handle the error in the catch block.
If an error occurs in the try block, the JavaScript engine immediately executes the code in the catch block. Also,
the JavaScript engine provides you with an error object that contains detailed information about the error.
fi
Basically, the error object has at least two properties:

• name speci es the error name.


• message explains the error in detail.
If no error occurs in the try block, the JavaScript engine ignores the catch block.

Note that web browsers may add more properties to the error object. For example, Firefox
adds lename, lineNumber, and stack properties to the error object.

It’s a good practice to place only the code that may cause an exception in the try block.
The following owchart illustrates how the try...catch statement works:

JavaScript try…catch statement examples


The following example uses the try...catch statement to handle the error:

try {
let result = add(10, 20);
console.log(result);
} catch (e) {
console.log({ name: e.name, message: e.message });
}
console.log('Bye');

Output

{name: 'TypeError', message: 'add is not a function'}


Bye
fi
fi
fl
In this example, we call the add() function and assign the return value to the result variable. Because
the add() function doesn’t exist, the JavaScript engine skips the statement that outputs the result to the
console:

console.log(result);

And it immediately executes the statement in the catch block that outputs the error name and message:

console.log({ name: e.name, message: e.message });

Since we already handled the error, the JavaScript engine continues to execute the last statement:

console.log('Bye');

Ingoring the catch block


The following example de nes the add() function that returns the sum of two arguments:

const add = (x, y) => x + y;

try {
let result = add(10, 20);
console.log(result);
} catch (e) {
console.log({ name: e.name, message: e.message });
}
console.log('Bye');

Output:

30
Bye

In this example, no error occurs because the add() function exists. Therefore, the JavaScript
engine skips the catch block.
fi
The exception identi er
When an exception occurs in the try block, the exception variable (e) in the catch block store the exception object.

If you don’t want to use the exception variable, you can omit it like this:

try {
//...
} catch {
//...
}

For example, the following uses the try…catch statement without the exception variable:

const isValidJSON = (str) => {


try {
JSON.parse(str);
return true;
} catch {
return false;
}
};
let valid = isValidJSON(`{"language":"JavaScript"}`);
console.log(valid);

How it works.
First, de ne the isValidJSON() function that accepts a string and returns true if that string is a valid JSON or false otherwise.

To validate JSON, the isValidJSON() function uses the JSON.parse() method and try...catch statement.

The JSON.parse() method parses a JSON string and returns an object. If the input string is not valid JSON,
the JSON.parse() throws an exception.

If no exception occurs, the function returns true in the try block. Otherwise, it returns false in the catch block.

Second, call the isValidJSON() function and pass a JSON string into it:

let valid = isValidJSON(`{"language":"JavaScript"}`);

Since the input string is valid JSON format, the function returns true.

Third, output the result to the console:

console.log(valid);

Summary
• Use the try...catch statement to handle exceptions in JavaScript.
• Place only the code that may cause an exception in the try block.
fi
fi
try…catch… nally
Summary: in this tutorial, you’ll learn how to use the JavaScript try...catch... nally statement to
catch exceptions and execute a block whether the exceptions occur or not

Introduction to the JavaScript try…catch… nally statement


The try...catch statement allows you to catch exceptions and handle them gracefully.
Sometimes, you want to execute a block whether exceptions occur or not. In this case, you
can use the try...catch... nally statement with the following syntax:

try {
// code may cause exceptions
} catch (error) {
// code to handle exceptions
} nally {
// code to execute whether exceptions occur or not
}

In this syntax, the nally block always executes after the try and catch blocks complete and whether exceptions occur or not.

The following owchart illustrates how the try...catch... nally works:


fi
fl
fi
fi
fi
fi
fi
fi
JavaScript try…catch… nally statement example
The following example illustrates how to use the try...catch... nally statement:

let result = 0;
try {
result = add(10, 20);
} catch (e) {
console.log(e.message);
} nally {
console.log({ result });
}

Output:

add is not de ned


{ result: 0 }

How it works.
First, declare the result variable and initialize its value with 0.

let result = 0;

Second, call the add() function and assign the return value to the result variable in the try block.
Because the add() function does not exist, the JavaScript engine raises an exception.

Because of the exception, the statement in the catch block executes to show the error message.

Third, output the result to the console in the try block.

In the following example, we de ne the add() function and call it in the try block:

const add = (x, y) => x + y;

let result = 0;

try {
result = add(10, 20);
} catch (e) {
console.log(e.message);
} nally {
console.log({ result });
}
fi
fi
fi
fi
fi
fi
Output:

{ result: 30 }

Because the add() function exists, no exception occurs in the try block. Therefore, the nally block
outputs the value of the result variable, which is the sum of 10 and 20.

In both examples, the nally block always runs.

try…catch… nally and return


The nally block always executes whether exceptions occur or not. Also, you can do nothing
to prevent it from executing including using a return statement. For example:

function fn() {
try {
return 1;
} catch {
return 2;
} nally {
return 3;
}
}

console.log(fn());

Output:

In this example, the return statement in the try block returns 1. Hence, the fn() function should have
returned 1. However, it is not the case.

Because the nally block always executes, the return statement in the nally block returns 3.
Therefore, the fn() function returns 3.

In other words, the return statements in the try and catch blocks are ignored in
the try...catch... nally statement.

Summary
• Use the nally clause in the try...catch... nally statement to execute a block whether exceptions
occur or not.
• The try...catch... nally statement ignores the return statement in the try and catch blocks because
the nally block always executes.
fi
fi
fi
fi
fi
fi
fi
fi
fi
fi
fi
fi
throw
Summary: in this tutorial, you’ll learn how to use the JavaScript throw statement to throw an exception.

Introduction to the JavaScript throw statement


The throw statement allows you to throw an exception. Here’s the syntax of the throw statement:

throw expression;

In this syntax, the expression speci es the value of the exception. Typically, you’ll use a new instance of
the Error class or its subclasses.

When encountering the throw statement, the JavaScript engine stops executing and passes the control to
the rst catch block in the call stack. If no catch block exists, the JavaScript engine terminates the script.

JavaScript throw exception examples


Let’s take some examples of using the throw statement.

1) Using the JavaScript throw statement to throw an exception


The following example uses the throw statement to throw an exception in a function:

function add(x, y) {
if (typeof x !== 'number') {
throw 'The rst argument must be a number';
}
if (typeof y !== 'number') {
throw 'The second argument must be a number';
}

return x + y;
}

const result = add('a', 10);


console.log(result);

How it works.

First, de ne the add() function that accepts two arguments and returns the sum of them. The add() function uses
the typeof operator to check the type of each argument and throws an exception if the type is not number.

Second, call the add() function and pass a string and a number into it.

Third, show the result to the console.

The script causes an error because the rst argument ("a") is not a number:
fi
fi
fi
fi
fi
Uncaught The rst argument must be a number

To handle the exception, you can use the try...catch statement. For example:

function add(x, y) {
if (typeof x !== 'number') {
throw 'The rst argument must be a number';
}
if (typeof y !== 'number') {
throw 'The second argument must be a number';
}

return x + y;
}

try {
const result = add('a', 10);
console.log(result);
} catch (e) {
console.log(e);
}

Output:

The rst argument must be a number

In this example, we place the call to the add() function in a try block. Because the expression in
the throw statement is a string, the exception in the catch block is a string as shown in the output.

2) Using JavaScript throw statement to throw an instance of the Error class


In the following example, we throw an instance of the Error class rather than a string in the add() function;

function add(x, y) {
if (typeof x !== 'number') {
throw new Error('The rst argument must be a number');
}
if (typeof y !== 'number') {
throw new Error('The second argument must be a number');
}
return x + y;
}
try {
const result = add('a', 10);
console.log(result);
} catch (e) {
console.log(e.name, ':', e.message);
}
fi
fi
fi
fi
Output:

Error : The rst argument must be a number

As shown in the output, the exception object in the catch block has the name as Error and the message as
the one that we pass to the Error() constructor.

3) Using JavaScript throw statement to throw a user-de ned exception


Sometimes, you want to throw a custom error rather than the built-in Error. To do that, you can de ne a
custom error class that extends the Error class and throw a new instance of that class. For example:

First, de ne the NumberError that extends the Error class:

class NumberError extends Error {


constructor(value) {
super(`"${value}" is not a valid number`);
this.name = 'InvalidNumber';
}
}

The constructor() of the NumberError class accepts a value that you’ll pass into it when creating a new
instance of the class.

In the constructor() of the NunberError class, we call the constructor of the Error class via the super and
pass a string to it. Also, we override the name of the error to the literal string NumberError. If we don’t do
this, the name of the NumberError will be Error.

Second, use the NumberError class in the add() function:

function add(x, y) {
if (typeof x !== 'number') {
throw new NumberError(x);
}
if (typeof y !== 'number') {
throw new NumberError(y);
}

return x + y;
}

In the add() function, we throw an instance of the NumberError class if the argument is not a valid number.

Third, catch the exception thrown by the add() function:


fi
fi
fi
fi
try {
const result = add('a', 10);
console.log(result);
} catch (e) {
console.log(e.name, ':', e.message);
}

Output:

NumberError : "a" is not a valid number

In this example, the exception name is NumberError and the message is the one that we pass
into the super() in the constructor() of the NumberError class.

Summary
• Use the JavaScript throw statement to throw a user-de ne exception.
fi
Optional catch binding
Summary: in this tutorial, you will learn how to use the optional catch binding in the try...catch statement.

Introduction to the optional catch binding


The try...catch statement is used to handle any errors that may occur. Generally, you place the code that
may cause an error in the try block and the code that handles the error in the catch block, like this:

try {
// code that may cause an error
} catch (error) {
// code that handles the error
}

In the catch block, you can access the Error object that contains detailed information on the error.

In practice, you may want to use the try...catch statement to check if a feature is implemented in the
web browser. If it isn’t, you want to fall back to a less desirable feature with broader support, for
example:

try {
// check if a feature is implemented
} catch (error) {
// fall back to a less desirable feature
}

In this case, the error object is declared but never used.

ES2019 introduced the optional catch binding that allows you to omit the catch binding and its surrounding
parentheses, like this:

try {

} catch {

Summary
• Since ES2019, you can omit the catch binding in the try...catch statement.
Section 7. JavaScript Runtime

Execution Contexts
Summary: in this tutorial, you will learn about the JavaScript execution context to deeply
understand how JavaScript code gets executed.

Introduction to the JavaScript execution context


Let’s start with the following example:

let x = 10;

function timesTen(a){
return a * 10;
}

let y = timesTen(x);

console.log(y); // 100

In this example:

• First, declare the x variable and initialize its value with 10.
• Second, declare the timesTen() function that accepts an argument and returns a value that is the result of
multiplication of the argument with 10.
• Third, call the timesTen() function with the argument as the value of the x variable and store result in the variable y.
• Finally, output the variable y to the Console.
Behind the scene, JavaScript does many things. in this tutorial, you will focus on execution contexts.

When the JavaScript engine executes the JavaScript code, it creates execution contexts.

Each execution context has two phases: the creation phase and the execution phase.

The creation phase


When the JavaScript engine executes a script for the rst time, it creates the global execution context.
During this phase, the JavaScript engine performs the following tasks:

• Create the global object i.e., window in the web browser or global in Node.js.
• Create the this object and bind it to the global object.
• Setup a memory heap for storing variables and function references.
• Store the function declarations in the memory heap and variables within the global execution context
with the initial values as unde ned.
fi
fi
When the JavaScript engine executes the code example above, it does the following in the creation phase:

• First, store the variables x and y and function declaration timesTen() in the global execution context.
• Second, initialize the variables x and y to unde ned.

After the creation phase, the global execution context moves to the execution phase.

The execution phase


During the execution phase, the JavaScript engine executes the code line by line, assigns
the values to variables, and executes the function calls.

For each function call, the JavaScript engine creates a new function execution context.

The function execution context is similar to the global execution context. But instead of creating the
global object, the JavaScript engine creates the arguments object that is a reference to all the
parameters of the function:
fi
In our example, the function execution context creates the arguments object that references all parameters
passed into the function, sets this value to the global object, and initializes the a parameter to unde ned.

During the execution phase of the function execution context, the JavaScript engine assigns 10 to the
parameter a and returns the result (100) to the global execution context:

To keep track of all the execution contexts, including the global execution context and
function execution contexts, the JavaScript engine uses the call stack, which you will learn in
the next tutorial.
In this tutorial, you have learned about the JavaScript execution contexts, including the global
execution context and function execution contexts.
fi
Call Stack
Summary: in this tutorial, you will learn about the JavaScript Call Stack which is a mechanism to
keep track of the function calls.

Introduction to JavaScript Call Stack


A call stack is a way for the JavaScript engine to keep track of its place in code that calls
multiple functions. It has the information on what function is currently being run and what
functions are invoked from within that function…
Also, the JavaScript engine uses a call stack to manage execution contexts:
• Global execution context
• function execution contexts
The call stack works based on the LIFO principle i.e., last-in- rst-out.
When you execute a script, the JavaScript engine creates a global execution context and
pushes it on top of the call stack.
Whenever a function is called, the JavaScript engine creates a function execution context for
the function, pushes it on top of the call stack, and starts executing the function.
If a function calls another function, the JavaScript engine creates a new function execution
context for the function being called and pushes it on top of the call stack.
When the current function completes, the JavaScript engine pops it off the call stack and
resumes the execution where it left off.
The script will stop when the call stack is empty.

JavaScript call stack example


Let’s start with the following example:

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

function average(a, b) {
return add(a, b) / 2;
}

let x = average(10, 20);


fi
When the JavaScript engine executes this script, it places the global execution context (denoted
by main() or global() function on the call stack.

The global execution context enters the creation phase and moves to the execution phase.

The JavaScript engine executes the call to the average(10, 20) function and creates a function
execution context for the average() function and pushes it on top of the call stack:

The JavaScript engine starts executing the average() since because the average() function is on
the top of the call stack.

The average() function calls add() function. At this point, the JavaScript engine creates another
function execution context for the add() function and places it on the top of the call stack:
JavaScript engine executes the add() function and pops it off the call stack:

At this point, the average() function is on the top of the call stack, the JavaScript engine executes
and pops it off the call stack.

Now, the call stack is empty so the script stops executing:


The following picture illustrates the overall status of the Call Stack in all steps:

Stack over ow
The call stack has a xed size, depending on the implementation of the host environment, either
the web browser or Node.js.

If the number of execution contexts exceeds the size of the stack, a stack over ow error will occur.

For example, when you execute a recursive function that has no exit condition, the JavaScript
engine will issue a stack over ow error:

function fn() {
fn();
}

fn(); // stack over ow

Asynchronous JavaScript
JavaScript is a single-threaded programming language. This means that the JavaScript engine has
only one call stack. Therefore, it only can do one thing at a time.

When executing a script, the JavaScript engine executes code from top to bottom, line by line. In
other words, it is synchronous.

Asynchronous means the JavaScript engine can execute other tasks while waiting for another task
to be completed. For example, the JavaScript engine can:

• Request for data from a remote server.


• Display a spinner
• When the data is available, display it on the webpage.
To do this, the JavaScript engine uses an event loop, which will be covered in the following tutorial.

Summary
• JavaScript engine uses a call stack to manage execution contexts.
• The call stack uses the stack data structure that works based on the LIFO (last-in- rst-out) principle.
fl
fl
fi
fl
fi
fl
Event Loop
Summary: in this tutorial, you’ll learn about the event loop in JavaScript and how JavaScript
achieves the concurrency model based on the event loop.

JavaScript single-threaded model


JavaScript is a single-threaded programming language. This means that JavaScript can do
only one thing at a single point in time.
The JavaScript engine executes a script from the top of the le and works its way down. It
creates the execution contexts, pushes, and pops functions onto and off the call stack in the
execution phase.
If a function takes a long time to execute, you cannot interact with the web browser during
the function’s execution because the page hangs.
A function that takes a long time to complete is called a blocking function. Technically, a
blocking function blocks all the interactions on the webpage, such as mouse click.
An example of a blocking function is a function that calls an API from a remote server.
The following example uses a big loop to simulate a blocking function:

function task(message) {
// emulate time consuming task
let n = 10000000000;
while (n > 0){
n--;
}
console.log(message);
}

console.log('Start script...');
task('Call an API');
console.log('Done!');

In this example, we have a big while loop inside the task() function that emulates a time-consuming
task. The task() function is a blocking function.

The script hangs for a few seconds (depending on how fast the computer is) and issues the
following output:

Start script...
Download a le.
Done!
fi
fi
To execute the script, the JavaScript engine places the rst call console.log() on top of the call stack and
executes it. Then, it places the task() function on top of the call stack and executes the function.

However, it’ll take a while to complete the task() function. Therefore, you’ll see the message 'Download a
le.' a little time later. After the task() function completes, the JavaScript engine pops it off the call stack.

Finally, the JavaScript engine places the last call to the console.log('Done!') function and executes it,
which will be very fast.

Callbacks to the rescue


To prevent a blocking function from blocking other activities, you typically put it in a callback
function for execution later. For example:

console.log('Start script...');

setTimeout(() => {
task('Download a le.');
}, 1000);

console.log('Done!');

In this example, you’ll see the message 'Start script...' and 'Done!' immediately. And after that, you’ll
see the message 'Download a le'.

Here’s the output:

Start script...
Done!
Download a le.
fi
fi
fi
fi
fi
As mentioned earlier, the JavaScript engine can do only one thing at a time. However, it’s more
precise to say that the JavaScript runtime can do one thing at a time.

The web browser also has other components, not just the JavaScript engine.

When you call the setTimeout() function, make a fetch request, or click a button, the web browser
can do these activities concurrently and asynchronously.

The setTimeout(), fetch requests, and DOM events are parts of the Web APIs of the web browser.

In our example, when calling the setTimeout() function, the JavaScript engine places it on the call
stack, and the Web API creates a timer that expires in 1 second.

Then JavaScript engine place the task() function is into a queue called a callback queue or a task queue:
The event loop is a constantly running process that monitors both the callback queue and the call stack.

If the call stack is not empty, the event loop waits until it is empty and places the next function from the
callback queue to the call stack. If the callback queue is empty, nothing will happen:

See another example:

console.log('Hi!');

setTimeout(() => {
console.log('Execute immediately.');
}, 0);

console.log('Bye!');

In this example, the timeout is 0 second, so the message 'Execute immediately.' should appear before the
message 'Bye!'. However, it doesn’t work like that.

The JavaScript engine places the following function call on the callback queue and executes it when the
call stack is empty. In other words, the JavaScript engine executes it after the console.log('Bye!').

console.log('Execute immediately.');

Here’s the output:

Hi!
Bye!
Execute immediately.
The following picture illustrates JavaScript runtime, Web API, Call stack, and Event loop:

In this tutorial, you have learned about the JavaScript event loop, a constantly running
process that coordinates the tasks between the call stack and callback queue to achieve
concurrency.
Hoisting
Summary: in this tutorial, you’ll learn about JavaScript hoisting and how it works under the hood.

Introduction to the JavaScript hoisting


When the JavaScript engine executes the JavaScript code, it creates the global execution context.
The global execution context has two phases:

• Creation
• Execution
During the creation phase, the JavaScript engine moves the variable and function declarations to
the top of your code. This is known as hoisting in JavaScript.

Variable hoisting
Variable hoisting means the JavaScript engine moves the variable declarations to the top of the
script. For example, the following example declares the counter variable and initialize its value to 1:

console.log(counter); // 👉 unde ned


var counter = 1;

In this example, we reference the counter variable before the declaration.

However, the rst line of code doesn’t cause an error. The reason is that the JavaScript engine
moves the variable declaration to the top of the script.

Technically, the code looks like the following in the execution phase:

var counter;

console.log(counter); // 👉 unde ned


counter = 1;

During the creation phase of the global execution context, the JavaScript engine places the
variable counter in the memory and initializes its value to unde ned.
fi
fi
fi
fi
The let keyword
The following declares the variable counter with the let keyword:

console.log(counter);
let counter = 1;

The JavaScript issues the following error:

"ReferenceError: Cannot access 'counter' before initialization

The error message explains that the counter variable is already in the heap memory. However, it
hasn’t been initialized.

Behind the scenes, the JavaScript engine hoists the variable declarations that use the let keyword.
However, it doesn’t initialize the let variables.

Notice that if you access a variable that doesn’t exist, the JavaScript will throw a different error:

console.log(alien);
let counter = 1;

Here is the error:

"ReferenceError: alien is not de ned

Function hoisting
Like variables, the JavaScript engine also hoists the function declarations. This means that the
JavaScript engine also moves the function declarations to the top of the script. For example:

let x = 20,
y = 10;

let result = add(x, y);


console.log(result); // 👉 30

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

Output:

30
fi
In this example, we called the add() function before de ning it. The above code is equivalent to the following:

function add(a, b){


return a + b;
}

let x = 20,
y = 10;

let result = add(x,y);


console.log(result); // 👉 30

During the creation phase of the execution context, the JavaScript engine places the add() function
declaration in the heap memory. To be precise, the JavaScript engine creates an object of
the Function type and a function reference called add that refers to the function object.

Function expressions
The following example changes the add from a regular function to a function expression:

let x = 20,
y = 10;

let result = add(x,y); // ❌ Uncaught ReferenceError: add is not de ned


console.log(result);

let add = function(x, y) {


return x + y;
}

If you execute the code, the following error will occur:

Uncaught ReferenceError: add is not de ned

During the creation phase of the global execution context, the JavaScript engine creates the add variable
in the memory and initializes its value to unde ned.

When executing the following code, the add is unde ned, hence, it isn’t a function:

let result = add(x,y);

The add variable is assigned to an anonymous function only during the execution phase of
the global execution context.
fi
fi
fi
fi
fi
Arrow functions
The following example changes the add function expression to the arrow function:

let x = 20,
y = 10;

let result = add(x,y); // ❌ Uncaught ReferenceError: add is not de ned


console.log(result);

let add = (x, y) => x + y;

The code also issues the same error as the function expression example because arrow
functions are syntactic sugar for de ning function expressions.

Uncaught ReferenceError: add is not de ned

Similar to the functions expressions, arrow functions are not hoisted.

Summary
• JavaScript hoisting occurs during the creation phase of the execution context that moves the
variable and function declarations to the top of the script.
• The JavaScript engine hoists the variables declared using the let keyword, but it doesn’t
initialize them as the variables declared with the var keyword.
• The JavaScript engine doesn’t hoist the function expressions and arrow functions.
fi
fi
fi
Variable scopes
Summary: in this tutorial, you will learn about the JavaScript variable scope that determines
the visibility and accessibility of variables.

What is variable scope


Scope determines the visibility and accessibility of a variable. JavaScript has three scopes:
• The global scope
• Local scope
• Block scope (started from ES6)

The global scope


When the JavaScript engine executes a script, it creates a global execution context.
Also, it also assigns variables that you declare outside of functions to the global execution
context. These variables are in the global scope. They are also known as global variables.
See the following example:

var message = 'Hi';

The variable message is global-scoped. It can be accessible everywhere in the script.

Local scope
The variables that you declare inside a function are local to the function. They are called local variables. For example:

var message = 'Hi';


function say() {
var message = 'Hello';
console.log(message);
}
say();
console.log(message);
Output:

Hello
Hi

When the JavaScript engine executes the say() function, it creates a function execution context.
The variable message declared inside the say() function is bound to the function execution context of
the function, not the global execution context.

Scope chain
Consider the following example:

var message = 'Hi';

function say() {
console.log(message);
}

say();

Output:

Hi
In this example, we reference the variable message inside the say() function. Behind the
scenes, JavaScript performs the following:
• Look up the variable message in the current context (function execution context) of
the say() function. It cannot nd any.
• Find the variable message in the outer execution context which is the global execution
context. It nds the variable message.
The way that JavaScript resolves a variable is by looking at it in its current scope, if it cannot
nd the variable, it goes up to the outer scope, which is called the scope chain.

More scope chain example


Consider the following example:

var y = 20;

function bar() {
var y = 200;

function baz() {
console.log(y);
}

baz();
}

bar();

Output:

200
fi
fi
fi
In this example:

• First, the JavaScript engine nds the variable y in the scope of the baz() function. It cannot nd any.
So it goes out of this scope.
• Then, the JavaScript engine nds the variable y in the bar() function. It can nd the variable y in the
scope of the bar() function so it stops searching.

Global variable leaks: the weird part of JavaScript


See the following example:

function getCounter() {
counter = 10;
return counter;
}

console.log(getCounter());

Output:

10

In this example, we assigned 10 to the counter variable without the var, let, or const keyword and then returned it.

Outside the function, we called the getCounter() function and showed the result in the console.

This issue is known as the leaks of the global variables.

Under the hood, the JavaScript engine rst looks up the counter variable in the local scope of
the getCounter() function. Because there is no var, let, or const keyword, the counter variable is not available in the
local scope. It hasn’t been created.

Then, the JavaScript engine follows the scope chain and looks up the counter variable in the global scope. The
global scope also doesn’t have the counter variable, so the JavaScript engine creates the counter variable in the
global scope.

To x this “weird” behavior, you use the 'use strict' at the top of the script or at the top of the function:

'use strict'

function getCounter() {
counter = 10;
return counter;
}

console.log(getCounter());
fi
fi
fi
fi
fi
fi
Now, the code throws an error:

ReferenceError: counter is not de ned

The following shows how to use the 'use strict' in the function:

function getCounter() {
'use strict'
counter = 10;
return counter;
}

console.log(getCounter());

Block scope
ES6 provides the let and const keywords that allow you to declare variables in block scope.
Generally, whenever you see curly brackets {}, it is a block. It can be the area within
the if, else, switch conditions or for, do while, and while loops.
See the following example:

function say(message) {
if(!message) {
let greeting = 'Hello'; // block scope
console.log(greeting);
}
// say it again ?
console.log(greeting); // ReferenceError
}

say();

In this example, we reference the variable greeting outside the if block that results in an error.
In this tutorial, you have learned about the JavaScript variable scopes including function
scope, global scope, and block scope.
fi
Section 8. Primitive Wrapper Types

Primitive wrapper types


Summary: in this tutorial, you will learn about the primitive wrapper types including Boolean, String, and Number.

Introduction to primitive wrapper types


JavaScript provides three primitive wrapper types: Boolean, Number, and String types.
The primitive wrapper types make it easier to use primitive values including booleans,
numbers, and strings.
See the following example:

let language = 'JavaScript';


let s = language.substring(4);
console.log(s); // Script

In this example, The variable language holds a primitive string value. It doesn’t have any method
like substring(). However, the above code works perfectly.

When you call a method on a variable that holds a number, a string, or a boolean, JavaScript
performs the following steps behind the scenes:

• Create an object of a corresponding type.


• Call a speci c method on the instance.
• Delete the instance immediately.
So the following code

let language = 'JavaScript';


let str = language.substring(4);

is technically equivalent to the following code:

let language = 'JavaScript';


// behind the scenes of the language.substring(4);
let tmp = new String(language);
str = temp.substring(4);
temp = null;
fi
Primitive wrapper types vs. reference types
When you create an object of a reference type using the new operator, the object will stay in
the memory until it goes out of scope.
The following variable s will stay on the heap until it goes out of the scope:

let s = new String('JavaScript');


console.log(s);

However, an automatically created primitive wrapper object exists for one line of code only.
See the following example:

let s = 'JavaScript';
s.language = 'ECMAScript';
console.log(s.language); // unde ned

In this example, we attempted to access the language property of the s variable and received
a value of unde ned instead of 'ECMAScript':

console.log(s.language); // unde ned

The reason is that the following code creates a String object and assigns a value to the language property.

s.language = 'ECMAScript';

However, the String object with the language property only exists during the execution of this line of code.

It’s not recommended to explicitly create primitive wrapper objects like the following:

let n = new Number(10);


let s = new String('JS');
let b = new Boolean(false);

However, you should know which methods are available for a primitive value in order to
manipulate it more effectively.
In this tutorial, you have learned about the JavaScript primitive wrapper types for Booleans,
numbers, and strings.
fi
fi
fi
Number
Summary: in this tutorial, you will learn about the JavaScript Number type and its useful methods
for working with numbers effectively.

Introduction to JavaScript Number type


Besides the primitive number type, JavaScript also provides the Number reference type for numeric values.

To create a Number object, you use the Number constructor and pass in a number value as follows:

var numberObject = new Number(100);

This example de ned a numberObject with a numeric value of 100.


To get the primitive value out of a Number object, you use the valueOf() method as follows:

console.log(numberObject.valueOf()); // 100

To get a number value as a string, you use the toString() or toLocaleString() methods.

The toString() method accepts an optional argument that determines the radix in which to present the number. The
radix (or base) is the number of unique digits that represent numbers in a positional numeral system.

For example, the decimal system uses ten digits from 0 through 9, therefore, the radix is 10.

See the following example:

var aNumber = new Number(10);


console.log(aNumber.toString()); // "10"

In this example the aNumber has a primitive value of 10, therefore, the toString() method returns 10
in the decimal system.

However, the following example returns the binary form of the aNumber variable.

console.log(aNumber.toString(2)); // "1010"

If you call a method on a primitive number value, JavaScript will convert it into a Number object
temporarily. This feature is called primitive wrapper types in JavaScript. For example:

let x = 10;
console.log(x.toString(16)); // "a"
fi
Formatting numbers
To format a number with a speci ed number of decimal points, you use the toFixed() method.

The toFixed() method accepts an argument that indicates how many decimal points should be used.

numberObject.toFixed(decimalPlaces);

The toFixed() method returns the corresponding string of the number using xed-point notation.
Here is an example.

var distance = 19.006


console.log(distance.toFixed(2)); // 19.01

distance = 19.004;
console.log(distance.toFixed(2)); // 19.00

It’s important to note that web browsers may use rounding methods differently. Therefore, you should be
careful when using the toFixed() method especially for applications that deal with monetary values.

To format a number in e-notation, you use the toExponential() method as shown in the following example.

var x = 10, y = 100, z = 1000;

console.log(x.toExponential());
console.log(y.toExponential());
console.log(z.toExponential());

// "1e+1"
// "1e+2"
// "1e+3"

To get a string representation of a number object to the speci ed precision, you use the toPrecision() method.

numberObject.toPrecision(precision);

The precision argument determines the number of signi cant digits.

The toPrecision() method returns the string representation of a Number object in exponential notation or xed point
rounded to precision signi cant digits.

Notice that if you omit the precision argument, the toPrecision() method will behave like the toString() method. See
the following examples:
fi
fi
fi
fi
fi
fi
let x = 9.12345;

console.log(x.toPrecision()); // '9.12345'
console.log(x.toPrecision(4)); // '9.123'
console.log(x.toPrecision(3)); // '9.12'
console.log(x.toPrecision(2)); // '9.1'
console.log(x.toPrecision(1)); // '9'

The e-notation may be returned in some cases for example:

x = 123.5;
console.log(x.toPrecision(2)); // "1.2e+2"

JavaScript Number object vs. primitive number


The following table illustrates the differences between a Number object and a primitive number:

Operator Number object Number value


typeof "object" "number"
instanceof Number true false

And here are examples:

let numberObject = new Number(10);


let number = 10;

// typeof
console.log(typeof numberObject);
console.log(typeof number);
// instanceof
console.log(numberObject instanceof Number); // true
console.log(number instanceof Number); // false

In this tutorial, you have learned about the Number type and some useful methods for formatting numbers.
String type
Summary: in this tutorial, you will learn about the JavaScript String type and how to manipulate
strings effectively.

Introduction to JavaScript String type


The String type is object wrapper of the string primitive type and can be created by using the String constructor as follows:

let str = new String('JavaScript String Type');

The String type has a property named length that speci es the number of characters in the string.

console.log(str.length); // 22

In this example, the value of the length property is 22 that also is the number of characters in the string 'JavaScript String Type'.

To get the primitive string value, you use one of the following methods of the String object: valueOf(), toString(), and toLocaleString().

console.log(str.valueOf());
console.log(str.toString());
console.log(str.toLocaleString());

To access an individual character in a string, you use square bracket notation [] with a numeric
index. The index of the rst character is zero as shown in this example:

console.log(str[0]); // J

The square bracket notation was introduced in ES5. Prior to ES5, you use the charAt() method, which is more verbose:

console.log(str.charAt(0)); // J

When you call a method on a primitive string variable or a literal string, it is converted to an
instance of the String type. For example:

'literal string'.toUpperCase();

This feature is known as primitive wrapper types in JavaScript.


fi
fi
String manipulation
The String type provides many useful methods for manipulating strings effectively. We will examine
each of them in the following section.

1) Concatenating strings
To concatenate two or more strings you use the concat() method as follows:

let rstName = 'John';


let fullName = rstName.concat(' ','Doe');
console.log(fullName); // "John Doe"
console.log( rstName); // "John"

The concat() method concatenates two or more strings and returns the result string. Note that
the concat() method does not modify the original string.

Besides the concat() method, you can also use the addition operator (+) for concatenating strings.
In practice, the addition operator is used more often than the concat() method.

let rstName = 'John';


let fullName = rstName + ' ' + 'Doe';
console.log(fullName); // "John Doe"

2) Extracting substrings
To extract a substring from a string, you use the substr() method:

substr(startIndex,[length]);

The substr() method accepts two arguments.

The rst argument startIndex is the location at which the characters are being extracted, while the
second argument length speci es the number of characters to extract.

let str = "JavaScript String";

console.log(str.substr(0, 10)); // "JavaScript"


console.log(str.substr(11,6)); // "String"

If you omit the length argument, the substr() method extracts the characters to the end of the string.
fi
fi
fi
fi
fi
fi
fi
Sometimes, you want to extract a substring from a string using starting and ending indexes. In this
case, you use the substring() method:

substring(startIndex,endIndex)

See the following example:

let str = "JavaScript String";


console.log(str.substring(4, 10)); // "Script"

3) Locating substrings
To locate a substring in a string, you use the indexOf() method:

string.indexOf(substring,[fromIndex]);

The indexOf() method accepts two arguments: a substring to locate and the fromIndex at which the
method starts searching forward in the string.

The indexOf() returns the index of the rst occurrence of the substring in the string. If the substring
is not found, the indexOf() method returns -1.

let str = "This is a string";


console.log(str.indexOf("is")); // 2

The following example uses the fromIndex argument:

console.log(str.indexOf('is', 3)); //5

To nd the location of the last occurrence of a substring in a string, you use the lastIndexOf() method.

string.lastIndexOf(substring,[fromIndex])

Unlike the indexOf() method, the lastindexOf() method searches backward from the fromIndex argument.

console.log(str.lastIndexOf('is')); // 5

The lastIndexOf() method also returns -1 if the substring is not found in the string as shown in this example:

console.log(str.lastIndexOf('are')); // -1
fi
fi
4) Removing whitespace characters
To remove all leading and trailing whitespace characters of a string, you use the trim() method.

let rawString = ' Hi ';


let strippedString = rawString.trim();
console.log(strippedString); // "Hi"

Note that the trim() method creates a copy of the original string with whitespace characters
stripped, it doesn’t change the original string.

ES6 introduced two new methods for removing whitespace characters from a string:
• trimStart() returns a string with whitespace stripped from the beginning of a string.
• trimEnd() returns a string with the whitespace stripped from the end of a string.

5) Changing cases
To change cases of a string, you use toLowerCase() and toUpperCase() methods:

let greeting = 'Hello';


console.log(greeting.toLowerCase()); // 'hello'
console.log(greeting.toUpperCase()); // 'HELLO';

In some languages, the rules for converting a string to lowercase and uppercase are very speci c.

Therefore, it is safer to use the toLocaleLowerCase() and toLocaleUpperCase() methods,


especially when you don’t know which language the code will deal with.

6) Comparing strings
To compare two strings, you use the localeCompare() method:

rst.localeCompare(second);

The localeCompare() returns one of three values: -1, 0, and 1.

• If the rst string comes before the second string alphabetically, the method returns -1.
• If the rst string comes after the second string alphabetically, the method returns 1.
• If two strings are equal, the method returns 0.
For example:

console.log('A'.localeCompare('B')); // -1
console.log('B'.localeCompare('B')); // 0
console.log('C'.localeCompare('B')); // 1
fi
fi
fi
fi
7) Matching patterns
The match() method allows you to match a string with a speci ed regular expression and get an array of results.

The match() method returns null if it does not nd any match. Otherwise, it returns an array containing the entire
match and any parentheses-capture matched results.

If the global ag (g) is not set, the element zero of the array contains the entire match. Here is an example:

let expression = '1 + 2 = 3';


let matches = expression.match(/\d+/);
console.log(matches[0]); // "1"

Output:

In this example, the pattern matches any number in the expression string.

In case the global ag ( g) is set, the elements of the result array contain all matches as follows:

let expression = '1 + 2 = 3';


let matches = expression.match(/\d+/g);

for (const match of matches) {


console.log(match);
}

Output:

1
2
3

In this example, the matches array contains all the matches including 1, 2, and 3 in the expression string.

If you only need to nd out if a string matches a regular expression, you use the search() method instead.

Similar to the match() method, the search() method accepts a regular expression and returns the position
of the string where the rst match is found. In case no match is found, it returns -1.

let str = "This is a test of search()";


let pos = str.search(/is/);
console.log(pos); // 2
fl
fi
fl
fi
fi
fi
8) Replacing substrings
To replace a substring in a string, you use the replace() method.

string.replace(regularExpression, replaceText)

The rst argument of the replace() method could be a regular expression or a string. If it is a regular expression,
the replace() method will nd the matches and replace them with the second argument ( replaceText). In case it is
a string, the replace() method will perform an exact search and carry the replacement.

The replace() method returns a copy of the original string after making the replacements.

The following example illustrates how to use a regular expression to replace the with a:

let str = "the baby kicks the ball";

// replace "the" with "a"


let newStr = str.replace(/the/g, "a");

console.log(newStr); // "a baby kicks a ball"


console.log(str); // "the baby kicks the ball"

And the following example shows how to replace kicks with holds by using the rst argument as a literal string.

newStr = str.replace('kicks', 'holds');


console.log(newStr); // "the baby holds the ball"

In this tutorial, you have learned about the JavaScript String type and how to manipulate strings effectively.
fi
fi
fi

You might also like