[go: up one dir, main page]

0% found this document useful (0 votes)
214 views141 pages

Hornbill Coding Society JavaScript Notes

The document is a comprehensive guide to JavaScript fundamentals and advanced concepts, structured into modules covering topics such as data types, functions, object-oriented programming, and asynchronous JavaScript. It emphasizes the importance of JavaScript in web development, both on the client and server sides, and outlines its evolution from its inception to modern usage. Additionally, it includes a preface with a story illustrating the value of proactive learning and anticipatory thinking in programming.

Uploaded by

Yash Raut
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)
214 views141 pages

Hornbill Coding Society JavaScript Notes

The document is a comprehensive guide to JavaScript fundamentals and advanced concepts, structured into modules covering topics such as data types, functions, object-oriented programming, and asynchronous JavaScript. It emphasizes the importance of JavaScript in web development, both on the client and server sides, and outlines its evolution from its inception to modern usage. Additionally, it includes a preface with a story illustrating the value of proactive learning and anticipatory thinking in programming.

Uploaded by

Yash Raut
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/ 141

2025

COMPLETE WEB DEVELOPMENT


JavaScript

Module – 3

JS fundamentals Number, Date, Intl


JS in browser : DOM & Events Object oriented programming
JS : behind the scenes Geolocation
Data structure Asynchronous JS: promise,
Modern operators async, await, Ajax
Functions Modules
Arrays
JAVASCRIPT
Web Development | Core concepts

EDITION : 2025
+91-9662332503 Hornbillcodingsociety.com

Gole ka Mandir, Morar, Gwalior (Madhya Pradesh) 474005


FORESTRY
Preface

There’s an old story from Bhartiya (Indian) Itihāsa that captures the essence of what it means to be truly
valuable—not just as a devotee, but as a learner and contributor.

One day, the Muni Nārada asked Lord Viṣṇu, “Why is the Mūrti of Garuḍa placed before you in every Mandira?
Am I not your most devoted follower?”
Viṣṇu smiled but didn’t respond immediately.

Just then, a loud crashing sound came from outside the gates of Vaikuṇṭha. Nārada looked around. Garuḍa,
who usually handled such disturbances, was missing.
“ I’ve sent Garuḍa on an errand,” said Viṣṇu. “Would you find out what happened? ”

Nārada ran out and came back. “A milkmaid (Gopi) tripped and fell.”
“What’s her name?” Viṣṇu asked.
Nārada rushed back and returned. “Śāradā.”
“Where was she going?”
“To the market,” said Nārada, after yet another trip.
“What made her fall?”
“She was startled by a snake that crossed her path.”
“Did the pot break?”
“I don’t know,” Nārada admitted.
“Can you check? I might want to buy some milk,” said Viṣṇu with a smile.
Nārada went out again and returned with a touch of pride. “One pot broke, but she still has some milk. She’s
willing to sell it—but at double the price.”
“And how much is that exactly?”
Nārada paused. “I forgot to ask.”

Viṣṇu chuckled, “It’s alright. Let me ask someone else.”

Just then, Garuḍa returned from his errand. Viṣṇu said, “There was a loud noise outside. Can you see what
happened?”

Garuḍa flew off and returned soon. “A milkmaid named Śāradā, on her way to the market, was startled by a
snake and fell. One pot of milk broke. Now she’s worried about how to recover the cost. I told her you might be
interested in the remaining milk—after all, you’re married to Lakṣmī, the goddess of wealth.”
“And the price?”
“She’s asking for four copper coins. Normally it would be one, but she thinks she might get more from a god.”

Viṣṇu smiled broadly. His eyes met Nārada’s. In that moment, Nārada understood why Garuḍa’s statue always
comes before Viṣṇu’s in Mandira.

Nārada had been obedient, but reactive—he followed instructions, one question at a time. Garuḍa, however,
was proactive. He thought ahead, anticipated every detail his master might need, and returned fully prepared.

This story serves as the foundation for how these JavaScript notes have been prepared.

Like Garud, the aim here is not just to provide answers, but to anticipate your questions, clarify your doubts
before you even voice them, and help you think deeply and clearly about the code you write.

Because true learning isn’t about waiting for instructions. It’s about seeing ahead.

ii Java Script|2025 +91-9662332503 Hornbillcodingsociety.com


JavaSCRIPT

Module - 3

CONTENTS
PART – I : Java Script basics 22. Destructuring 79 - 84

1. JavaScript introduction 1-5 23. Spread, Rest operator 85 - 90

2. Linking JS file 6-7 Short circuiting, Nullish


24. 91 - 95
Coalescing
3. Values and variable 8 - 10 Enhanced object literal,
25. 96 - 98
option chaining
4. Data types in JS 11 - 13
26. Set, Map 99 - 106
5. Operators in JS 14 - 16
27. String properties& method 107 - 109
6. Template literals 17 - 18
28. Functions in details 110 - 116
Type conversion &
7. 19 -21
coercion 29. Closures 117 - 122
8. Equality, Boolean logic 22 - 23
30. Advanced array method 123 - 133
Conditional control
9. 24 - 28 31. Number and dates 134 - 142
statement

10. Strict mode 29 - 31 32. Object oriented programming 143 - 152

11. Functions in JS 32 - 34 33. Classes 153 - 159

12. Arrays 35 - 37 34. Encapsulation 160 - 164

13. Object 38 - 42 Geolocation, Local storage,


35. 165 - 170
session storage
14. Looping statement 43 - 47 Asynchronous JS, await,
36. 171 - 176
promise, async/await,Api
Part II Advanced Java Script
37. Ajax calls 177 - 182
15. JS interaction with DOM 48 - 49
38. Error handling 183 - 187
16. How JS Works 50 - 55
39. Modules 188 - 194
Execution context & call
17. 56 - 61
stack 40. NPM, Bable, Pollyfill 195 - 197
18. Variable environment 62 - 65
41. Declarative vs functional JS 198 - 200
19. This Keyword 66 - 69

Arrow function vs. normal


20. 70 - 72
function

21. Memory management 73 - 78

Copyright © by Hornbill coding society


All rights are reserved. No part of this document may be reproduced, stored, or transmitted in any form or by any
electronic, photocopying, recording, or otherwise, without prior permission of Hornbill coding society.

© Hornbill coding society +91 9662332503 Hornbillcodingsociety@gmail.com iii


YouTube

Adarsh colony, Gole ka Mandir, Morar,


Gwalior (Madhya Pradesh), 474005
Introduction to Java Script
CHAPTER

JavaScript is a high-level, interpreted, dynamic, multi-paradigm, Chapter Outline


programming language that is used to add interactivity to web page.
1.1 What is JavaScript
1. 1 DEFINITION
Definition

high-level : focus on human-friendly syntax, utilizing symbolic 1.2 Java Script in real world
representations, natural language elements, and automatic memory JavaScript is evergreen

management to simplify program development. 1.3 Why JS matters


ubiquity
Interpreted: code is executed line by line by an interpreter, without versatility
needing to be compiled into machine code beforehand.
Community and Ecosystem

dynamic programming language: support runtime modification Evolving role

of program variable and functions. 1.4 Evolution of JS


Genesis
multi-paradigm language: supports various programming styles,
Stagnation
including imperative programming, declarative programming,
Modern Era
functional programming, object-oriented programming (OOP), and
1.5 Industry use
procedural programming.
1.6 Interview Question’s
1.2 JAVASCRIPT IN THE REAL WORLD: KEY USE CASES

Backend framework

Front end framework

Figure 1.1 : Use case of Java Script

HTML, CSS, and JavaScript are the foundational technologies for the
web. These three technologies all work together to create beautiful,
interactive and dynamic websites or web applications.
JavaSCRIPT

HTML CSS JavaScript

Defines the structure and content Controls the visual presentation Adds interactivity and dynamism
of a webpage, specifying elements of content, managing aspects like to the webpage, enabling
such as text, images, and buttons. colours, fonts, and layout. It can be manipulation of content and
It can be loosely compared to the likened to the car's exterior, styles, fetching data from servers,
chassis of a car. including the body, bumper, and and building complex web
headlights. applications. It can be compared to
the engine of a car.

JavaScript is evergreen

JavaScript is the cornerstone of modern web development, both on the front end and the back end.

✓ Front-End Development: JavaScript forms the basis of popular frameworks such as Angular ,
React , and Vue.js , simplifying the creation of dynamic user interfaces. While the popularity of
individual frameworks may change, JavaScript's foundational role is secure.
✓ Back-End Development: Node.js allows JavaScript to be used on the server-side, enabling full-
stack development within a single language.
✓ Cross-Platform Applications: JavaScript's versatility extends beyond web browsers, enabling the
development of native mobile applications (using React Native and Ionic) and desktop applications
(using Electron).

1.3 WHY JS MATTERS

Why JavaScript Matters

These differences highlight JavaScript's unique role in the modern web development landscape:

• Ubiquity : It's the de facto language for front-end development, making it essential for web developers.

• Versatility : Its ability to run on both the client-side and server-side expands its applications beyond the
browser.

• Community and Ecosystem : A large and active community drives constant innovation and a rich ecosystem
of libraries and frameworks.

• Evolving Role : JavaScript continues to evolve, with new features and applications emerging regularly.

In essence, while other languages have their strengths, JavaScript's unique combination of features and its
central role in web development make it a vital skill for anyone aspiring to work in this field of web development.

2 Java Script | 2025 +91 9662332503 Hornbillcodingsociety@gmail.com


JavaSCRIPT

Web application on Browser Frontend Web application on Browser Backend

Native Mobile Application Native Desktop Application

Figure 1.2 : Use case of Java Script with framework in various application

1.4 EVOLUTION OF JAVASCRIPT

The Evolution of JavaScript: From Mocha to Modern Web Powerhouse


The need for interactive web pages arose soon after the internet's inception and the
development of the first web browsers. This need spurred the creation of JavaScript, a
language that has profoundly shaped the modern web.

I. The Genesis (1995-1999): From Mocha to ECMAScript


In 1995, Netscape Navigator, the dominant browser at the time, tasked Brendan Eich with
creating a scripting language for its browser. In just 10 days, "Mocha" was born. In 1996 renamed
to LiveScript and then, strategically, to JavaScript, leveraging the popularity of Java for marketing
purposes.

📝:- There is no relation between the Java and Java Script Whatsoever, these are two separate and different languages.

Simultaneously, Microsoft introduced JScript with Internet Explorer. While functionally similar, this separate
implementation led to fragmentation and the need for standardization. JavaScript was entrusted to the
independent body, the European Computer Manufacturers Association (ECMA), to oversee its
standardization and updates.

Year Events Significance


1995 Mocha (Brendan Eich, Netscape) Initial creation of the language.
1996 LiveScript (Renamed) Brief interim name.
1996 JavaScript (Renamed) Strategic renaming to associate with Java.
1996 JScript (Microsoft) Competing implementation, highlighting the need for
standardization.
1997 ECMAScript 1 (ES1) First standardized version, laying the foundation for
interoperability.
1998 ECMAScript 2 (ES2) Minor updates and clarifications to ES1.
1999 ECMAScript 3 (ES3) Significant improvements and features, establishing a more
robust language. This version saw wide adoption.

© Hornbill Coding Society +91 9662332503 Hornbillcodingsociety.com 3


JavaSCRIPT

II. A Period of Stagnation and Revival (2000-2009)


early 2000s, the development of ECMAScript faced significant challenges. ES4, intended as a major update, was
ultimately abandoned due to disagreements over its direction.

Year Events Significance

2000- ES4 Development and A period of internal conflict and disagreement led to the abandonment
2008 abandonment of a major planned update.
2009 ECMAScript 5 (ES5) Introduced important features like "strict mode," JSON support, and
improved object and array manipulation methods. This version
stabilized the language.

III. The Modern Era (2015-Present) : A Renaissance


The release of ES6 (ES2015) in 2015 marked a significant milestone as the most substantial update to the to date.
This version brought a wide range of new features, greatly enhancing JavaScript's functionality and developer
experience. Since then, ECMAScript has embraced an annual release cycle, fostering ongoing improvement and
innovation.

Year Events Significance

2015 ECMAScript 6 Revolutionary update: let and const, arrow functions, classes,
(ES6/ES2015) modules, template literals, destructuring, promises, and much
more. This modernized the language and significantly improved
developer productivity.
2016- Yearly Releases (ES2016, Continuous improvements and additions, including
Present ES2017, ES2018, ES2019, async/await, shared memory, object rest/spread properties,
ES2020, ES2021, ES2022, and more. This rapid iteration keeps JavaScript evolving and
ES2023, etc.) relevant to the ever-changing web landscape.

JavaScript boasts backward compatibility all the way back to ES1, ensuring that code written in 1997 functions
seamlessly alongside code written today. This adherence to the "do not break the web" principle by ECMA
ensures that nothing is ever removed from the language—only additions are made. As a result, new versions are
essentially incremental updates that introduce new features, making them more like "releases" rather than
entirely new versions.
Other languages like C, C++, Java, Python (partially), and Perl also support backward compatibility to varying
degrees.

Key Notes: 📝
• Modern JavaScript: The term applies to ES6 (2015) and later versions.
• Future Releases: Versions from ES2021 onwards are referred to as "future releases."
• No Forward Compatibility: Code written for future versions (e.g., ES2050) will not work in today's
browsers due to the lack of forward compatibility.

1.5 INDUSTRY USE

JavaScript was initially created for web browsers but has expanded to other areas like server-side programming
(Node.js) and mobile app development.

Essentially all the websites you see on internet uses JavaScript as there is no alternative available to JS

4 Java Script | 2025 +91 9662332503 Hornbillcodingsociety@gmail.com


JavaSCRIPT

1.6 INTERVIEW QUESTIONS

• What is Java Script?


• What is ECMA standards?
• What is backward compatibility in case of Java Script?
• What are the popular framework that are based on JS enumerate?
• Why ES6 2015 Release of JS is considered as revolutionary?

© Hornbill Coding Society +91 9662332503 Hornbillcodingsociety.com 5


Linking Js File
CHAPTER

Since JavaScript is primarily used in browsers, it needs to be Chapter Outline


embedded in an HTML file to execute in a browser environment. This
is the standard way to run JavaScript files. Alternatively, standalone 2.1 Methods to link JS file
JavaScript files can be executed in a Node.js environment. Inline Script

External Script
2.1 METHODS TO LINK JS FILE WITH HTML
2.2 Why external Java Script
Inline script : Place the <script></script> tag within the HTML file is necessary
and write the JavaScript code directly between the opening and 2.3 Interview Questions
closing <script> tags.

External script : Create a separate file with a “.js “extension, such as


script.js., and write your JavaScript code within it.

Include the <script> tag with the src attribute in your HTML file to
specify the path to your JavaScript file, for example: <script
src=”script.js”></script>

The <script> tag can be placed in the <head> section or just before
the closing </body> tag.

<head>
<script src="script.js"></script>
</head>
<!-- Linking JavaScript before the closing body tag -->
<body>
<!-- Other content -->
<script src="script.js"></script>
</body>

Note: Choose Either one of these

2.2 WHY EXTERNAL JAVASCRIPT IS NECESSARY

• Separation of Concerns : Keeping HTML and JavaScript in


separate files makes code easier to read, maintain, and debug.
JavaSCRIPT

• Reusability : A single JavaScript file can be linked to multiple HTML pages, promoting code reuse and
reducing redundancy.
• Improved Performance :
External JavaScript files can be cached by browsers, reducing load time on subsequent visits.
Deferring or placing the <script> tag at the bottom prevents blocking the rendering of HTML, enhancing
user experience.
• Scalability : As project grows, managing a single script file becomes more convenient than embedding
JavaScript directly in your HTML.
• Version Control and Collaboration : Teams can work on JavaScript files independently, streamlining the
development process.

2.3 INTERVIEW QUESTIONS

• How to connect Js File to HTML/DOM?


• What are the ways to connect JS File?
• How can a standalone JavaScript file be executed outside of a browser environment?
• What are the benefits of using a separate JavaScript file in web development?

© Hornbill Coding Society +91 9662332503 Hornbillcodingsociety.com 7


Values and Variable
CHAPTER

A value is a piece of data and the most fundamental unit of information Chapter Outline
in programming. One of its key uses is the ability to store it for repeated
use. Typically, values are stored in various data storage containers or 3.1 Variabe naming
data types available in JavaScript. These containers are given a name, convention
referred to as a variable. Variables enable developers to assign
Camel case
meaningful labels to data, enhancing code readability and
Pascal case
maintainability.
Small case

3.1 VARIABLE NAMING CONVENTIONS Snake case

Upper case
There are conventions for declaring variables, which are standard
3.2 Variable naming rules
practices designed to ensure consistency in coding. However, deviating
3.3 Assignment to variable
from these conventions does not impact the execution of the program
3.4 Declering variabke in JS
in any way.
3.5 Interview Questions
 Camel Case : Commonly used for variable names in JS. e.g.,
firstName = “Elon”, totalAmount = 30
 Pascal Case/Upper Camel case : first letter of each word (including
first word) in a compound identifier is capitalized,with no space or
underscore in between e.g., const CustomerService, UserProfile
 Small case : as the uppercase variable is generally reserverd for class
Name. e.g., salary = 2000
 Snake Case : Sometimes used, particularly in constants python and
Ruby developer have convetion to use this. e.g., first_name =
“Musk”, total_amount = 30
 Uppercase for Constants : Use uppercase letters with underscores
for constants. e.g., PI = 3.14, MAX_LIMIT = 100
 Descriptive : variable name should be descriptive of data they hold
e.g., neighboursName = “Donald Trump”

3.2 VARIABLE NAMING RULES

JavaScript has specific rules for naming variables that must be followed,
as violating these rules can affect the execution of the code.
JavaSCRIPT

Valid Characters : Variable names can include letters, numbers, underscores (_), and dollar signs ($). e.g.,
userName, _id, $price

Start with a Letter : Names must begin with a letter, underscore, or dollar sign, but not a number.
Valid : _value, $amount
Invalid : 9name

Case Sensitivity : Variable names are case-sensitive. userName and username are treated as different variables.

No Reserved Keywords : Variable names cannot use JavaScript reserved keywords like var, let, const, if, etc.
Invalid : let const = 5;

Note:- There are some reserved keyword which can be used as variable i.e name, though it works but still it
is recommended to avoid them

3.3 ASSIGNMENT OF VALUE TO VARIABLE

A value is assigned to a variable using the = (assignment operator). Variables can store different data types,
including but not limited to:

Strings : Text data, enclosed in single or double quotes.

Numbers : Numeric values.

Booleans : true or false.

Objects : Collections of key-value pairs.

Arrays : Ordered lists of values.

Undefined : A variable that has been declared but not assigned a value.

Null : A value representing no value or emptiness.

3.4 DELARING VARIABLE IN JAVA SCRIPT

There are four way in which variable in Java Script can be declerd

let: Introduced in ES6, it is block-scoped and ideal for variables that may change during the program's execution.

e.g., let speed = 30;

speed = 40;

const: Introduced in ES6, it is block-scoped and used for variables that should remain constant after being
assigned a value. They can’t be reassigned new value. e.g., const birthyear = 2002

var: An older way to declare variables. It has a function scope and is less commonly used in modern JavaScript
and should be avoided it works same as let i.e., can be reassigned.

e.g., var neighboursName = “Donald Trump”

variable can be declared directily by writing the name of variable and storing value in it, However it by default
treated as variable declared with Var keyword e.g., presidentOfUsa = “Donald Trump”

© Hornbill Coding Society +91 9662332503 Hornbillcodingsociety.com 9


JavaSCRIPT

Note:- These keywords are used only when declaring a variable, and there is no need to use them when
reassigning a value.

3.5 INTERVIEW QUESTIONS

• What is value and How is is it stored in JS ?


• What are the conventions for decleration of variable name ? (Infosys, TCS, mindtree)
• What are the rules for declaring the variable name in JS ? (Infosys, TCS, mindtree)
• What is the difference between let, const and Var Variable ?

10 Java Script +91 9662332503 Hornbillcodingsociety@gmail.com


CHAPTER

4 Data Types in Java Script

In programming, values can belong to various types, and the Chapter Outline
classification of these types varies across languages. In JavaScript, every
value is either an object or a primitive. A value is considered primitive if 4.1 Data types in JS
it is not an object. In this chapter, we will explore the primitive data types
Pimitive
in JavaScript.
4.2 Comments in JS
4.3 Checking value type
4.1 DATA TYPES IN JS 4.4 Interview Question’s
Primitive Data Type Objects
PRIMITIVE DATA TYPES
Number Arrays
1. Numbers : JS number are
always floating point String Objects

number. i.e., they always


Boolean Functions
have decimal point
attached to them even if not Undefined Date
seen or isn’t define explicity
Null JSON
e.g., const age = 24; // 24.0

const PI = 3.14; Symbol Promise, error

2. String : Represents textual Big Integer Map, Set


data, sequence of
Figure 4.1 : Data Types in JS
characters.
Strings are enclosed in single quotes ('), double quotes ("), or
backticks (`).
e.g., const firstName = “joe” or ‘Joe’, `Joe` - (Valid)
let greeting = `Hello, ${name}` - (Valid)
const lastName = “Biden’ or `Biden” - (Invalid)

Note: while crafting string quotes must be same

3. Boolean : Represents logical values: true or false. Commonly used


in conditional statements to take decisions.
let isAvailable = true;
4. Undefined : Represents a variable that has been declared but not
assigned a value. (empty value)
JavaSCRIPT

let x;
console.log(x); // undefined
5. Null : Represents an intentional absence of value. It is often used to indicate "no value" or "empty."
let emptyValue = null;
console.log(emptyValue); // undefined
6. Symbols : Introduced in ES6, it represents a unique identifier. Used for object property keys to avoid naming
conflicts.
let sym = Symbol("id");
7. BigInt : In JavaScript, numbers are internally represented as 64-bit values (64 ones and zeros). Out of these,
53 bits are used to store the digits, while the remaining bits are reserved for the decimal point and sign. This
creates a limitation on representing very large numbers accurately. For integers larger than the safe limit of
the Number type (2^53 - 1), special handling is required.

consol.log(number.MAX_SAFE_INTEGER); // 9007199254740991
let largeNumber = 123456789012345678901234567890n

Note: Mathematical operations cannot be performed directly between a Number type and a BigInt.
The Number must first be converted to a BigInt, either by appending n or by passing it to the
BigInt constructor, like BigInt(1254585).

let result = 23 * 25n // error


result = 23n * 23n or 23n * BigInt(23);

JavaScript is dynamically typed, meaning we don't need to specify the type of data a variable will store
beforehand. The data type of a variable can change throughout the program. We can assign a value of one
data type to a variable that previously stored a value of another data type. JavaScript automatically
determines the type of the value when it's assigned to the variable, so the variable itself doesn't have a fixed
type; instead, it's the value that determines the type in JavaScript.

4.2 COMMEMT FACILITY IN JS

In JavaScript, we can comment out a line of code by placing // at the beginning of the line. This line will be
completely ignored during execution, making it useful for organizing code into sections or explaining the
functionality of specific parts of the code.
short cut key : Ctrl + /
Multiline comment : we can use /* code */

4.3 CHECK TYPE OF VALUE

We have typeof property available with us to check the type of value

e.g., console.log(typeof 23) // Number

console.log(typeof False) // Boolean

Note: The value and type of undefined it is Undefined

12 Java Script +91 9662332503 Hornbillcodingsociety@gmail.com


JavaSCRIPT

let x;
console.log(x) // undefined
console.log(typeof x) // undefinde
console.log(typeof null) // Object || This is bug in language.

On the other hand, null represents the intentional absence of a value. While both null and undefined may seem
similar, they are not the same because...

console.log(undefined === null) // false || type of null is object and type of undefined is undefined

console.log(undefined == null) // True || null’s value is undefined or empty value

The ECMA Script specification defines that null and undefined are loosely equal.

4.4 INTERVIEW QUESTIONS

• What are the data types in JS ? (aksed in almost all inteview)


• What are primitive data types in JS ?
• How to check the datatype of value in js ?
• How comments are added in JS ?

© Hornbill Coding Society +91 9662332503 Hornbillcodingsociety.com 13


CHAPTER Operators & Precedence
of Execution
5

In JavaScript, operators are special symbols or keywords that perform Chapter Outline
operations on values and variables. They are the building blocks of
JavaScript expressions, allowing you to manipulate data in various ways. 5.1 Basic operators in JS
For example, the + operator adds two numbers together, and the =
Arithmatic
operator assigns a value to a variable.
Comparison
5.1 BASIC OPERATORS IN JS Logical

1. Arithmatic operator : Perform basic mathematical calculations. Assignment

String
+ Addition 5+3=8
Ternary
- Subtraction 5-3=2
* Multiplication 5 * 3 = 15 Unary

/ Division 5 / 3 = 1.67 5.2 Operator precedence

% Modulus - returns remainder of a 5%3=2 Table

division 5.3 Interview Questions

2. Comparison operator / relational operator : Compare values and


return a Boolean

== Equal to (loose equality) 5 == '5' (true)


=== Strict equality 5 === '5' (false)
!= Not equal to (loose inequality). 5 != '5' (false)
!== Strict not equal to 5 !== '5' (true)
> Greater than 5 > 3 (true)
< Less than 5 < 3 (false)
>= Greater than or equal to 5 >= 5 (true)
<= Less than or equal to 5 <= 5 (true)

3. Logical operator: Perform logical operations


&& (AND) Returns true if both operands are T &&T = T
true
|| (OR) Returns true if at least one operand F || F = F
is true.
! (NOT) Reverses the Boolean value !T=F
JavaSCRIPT

4. Assignment operator let x= 10

+= Addition Assignment x += 5; // x = x + 5 => x = 15


-= Subtraction Assignment x -= 3; // x = x - 3 => x = 7
*= Multiplication Assignment x *= 3; // x = x * 3 => x = 30
/= Division Assignment x /= 2; // x = x / 2=> x = 5
%= Modulus Assignment x %= 3; // x = x % 3 => x = 1
**= Exponentiation Assignment x **= 3; // x = x ** 3 => x = 1000

5. String operator: + Operator is also used to concatenate string or Join string


e.g., console.log(“Sachin”+ “ ”+ “Tendulkar”) // Sachin Tendulkar

6. Conditional (Ternary) operator : Shortcut for if-else


Syntax: condition ? value_if_true : value_if_false
e.g., x > 10 ? 'Yes' : 'No'
7. Unary operator
+ Unary plus: Converts the operand to a number (if it's not console.log(+"10.5"); // 10.5
already). console.log(+true); // 1
console.log(+null); // 0
- Unary Negation: Negates the operand or converts it to a console.log(-“5”); // -5
number and then negates it console.log(- true); // -1
console.log(- false); // 0
console.log(- null); // 0
X++ Post Increment: increase count by 1, returns current log(X++) // x=x+1 //10
value, then increments let x=10 Log(x) = 11
++X preIncreament: Increments the operand before returning Log(++x) // 11
its value. Let x=10
--X Predecreament operator: Decrements the operand before Log(--x) //9
returning its value.
X-- Postdecreament: Returns the value of the operand before x++ //x =x-1 x =>9
decrementing it.
! Logical NOT: negates the value ! TRUE = FALSE

8. Spread and Rest operators - This topic will be discussed in detail in a separate chapter.
9. Destructuring operators - This topic will be discussed in detail in a separate chapter.

5.2 OPERATOR PRECEDENCE TABLE

Operator precedence determines the sequence in which operations are executed in an expression containing
multiple operators. Operators with higher precedence are evaluated before those with lower precedence. While
most operators are executed from left to right, some follow a right-to-left execution order. Below is a sample of
the operator precedence table. The complete table can be found on the MDN documentation website.

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Operator_precedence

© Hornbill Coding Society +91 9662332503 Hornbillcodingsociety.com 15


JavaSCRIPT

Precedence Operator Type Associativity

Highest Parentheses ()’ Left-to-right


Member Access . Left-to-right
Exponentiation ** Right-to-left
Unary +, -, ! Right-to-left
Multiplication, Division Left-to-right
Addition, Subtraction Left-to-right
Comparison Left-to-right
Logical AND && Left-to-right
Logical OR `
Assignment =, +=, etc. Right-to-left

Lowest Comma , Left-to-right

5.3 INTERVIEW QUESTIONS

• What are the operators in JS ?


• What is preincreament and postincreament operator and what is the difference between them ?
• How JS decides the order of execution of the operator ?
• What are the method available in JS to concatenate string ? (Infosys)

16 Java Script +91 9662332503 Hornbillcodingsociety@gmail.com


Template Literals
CHAPTER

String operations can encompass various tasks such as concatenating Chapter Outline
two strings, adding spaces, or incorporating dynamic data—whether
numbers or strings—into a string. While these tasks may appear 6.1 String operations
straightforward, they can become cumbersome with regular strings.
Normal string
Managing multiple concatenation operators, numerous quotation
Template string
marks, and handling scenarios where quotation marks need to be
6.2 Multiline string
embedded within the string can complicate the process. The challenge
Normal string
intensifies further when dealing with multiline strings or comments.
Template string
Template string literals, introduced in ES6, are a way to create strings
6.3 Interview Question’s
that allow embedding expressions and multi-line strings using
backticks ( ` ` ). Unlike regular strings, template literals provide
enhanced flexibility and readability.

const GringottsWizardingBankCredit = 50000;

const shoppingExpence = 2300;

const firstName = “Harry”;

const schoolName = “Hogwarts School of Witchcraft and Wizardry”

6.1 STRING OPERATIONS

NORMAL SRTRING

const wizard = “My name is ”+ firstName + “ I study in ”+ schoolName


I went for shopping flying broom it coted me ” + shoppingExpense + “.
Now I have ” + (GringottsWizardingBankCredit -shoppingExpense)+”
left in my Bank accounts”

USING STRING TEMPLATE LITERALS

Const wizard = `My name is ${firstName} I study in ${schoolName} I


went for shopping flying broom it coted me ${shoppingExpense}. Now
I have ${totalGreenGautsBankCredit-shoppingExpense} left in my
Bank accounts`
JavaSCRIPT

With template strings, inserting complex data such as mathematical calculations or dynamic data from variables
becomes straightforward, eliminating the need for multiple single or double quotes.

The concept is simple: everything inside backticks is treated as a string, while anything within ${ } is evaluated
as an expression or dynamic data.

6.2 MULTILINE STRING

NORMAL SRTRING
Creating multiline strings is a cumbersome process, as shown below.

“My name is harry Potter \n\ I studty in Hogwarts School of Witchcraft and Wizardry \n\ and my address is house
at 4 Privet Drive, Little Whinging, Surrey ”

TEMPLATE STRING LITERALS


Using template string literals makes creating multiline strings much easier. simply place the string within
backticks and press Enter whenever you want to start a new line.

` My name is harry Potter I studty in Hogwarts School of Witchcraft and Wizardry and my addredd is house at 4
Privet Drive, Little Whinging, Surrey `

6.3 INTERVIEW QUESTIONS


• What is template string ?
• How to add data dyanamically in the string ? (TCS, Accenture, infosys)
• How to write multiline string in the JS?

18 Java Script +91 9662332503 Hornbillcodingsociety@gmail.com


CHAPTER
Type Conversion &
7
Coercion

In programming, there are times when we need to convert data from Chapter Outline
one type to another. JavaScript offers two approaches for this: Type
conversion and Type coercion. 7.1 Type conversion
Number to string
7.1 TYPE CONVERSION
String to Number
“Type conversion”, also known as explicit conversion, is when a
Invalid conversion
developer explicitly converts a value from one data type to another.
7.2 Truthy and Falsy value
JavaScript provides methods and functions to perform these conversions
Converting to boolean
intentionally.
7.3 Type coercion
• CONVERTING NUMBER TO STRING String coercion

const num = 123; Number coercion

const str = String(num); // Explicit conversion to a string Boolean coercion

console.log(typeof str); // string 7.4 Interview Questions

• CONVERTING STRING TO NUMBER


const weight = “123”
const weightNumber = Number(weight) // Explicit conversion to a
number
console.log(typeof weightNumber, typeof weight); // Number , string
original value is not conveted

• INVALID CONVERSION : We can’t convert everything into number


e.g., string

console.log(Number(‘Emanual Kant’)) // NaN (Not a number)

NaN here means invalid number i.e., not really a not a number. The data
type of NaN is Number

console.log(typeof NaN); // Number

Note: JS convert only 2-3 types these are


• Number to String
• String to Number
• Number to Boolean
JavaSCRIPT

7.2 TRUTHY AND FALSY VALUE

• CONVERTING TO BOOLEAN : Falsy values are not inherently false but are treated as false when converted
to a Boolean. In JavaScript, there are five falsy values in addition to false itself.
1. 0
2. ““
3. Undefined
4. Null
5. NaN

Everything except these five value will convert to True i.e., Truthy Value e.g., Any string, all number except 0,
const value = " ";
const isTruthy = Boolean(value); // Converts to `false` as the string is empty
console.log(isTruthy); // false
console.log(Boolean(“ ”)) // false
console.log(Boolean(undefined)) // false
console.log(Boolean(Null)) // false
console.log(Boolean(NaN)) // false
console.log(Boolean(“Ram”)) // true
console.log(Boolean({ }) // empty object : true

7.3 TYPE COERCION

Type coercion, also known as implicit conversion, occurs when JavaScript automatically converts one data type
to another during operations. This can sometimes lead to unexpected results, especially with loose equality (==)
and arithmetic operations.

• STRING COERCION

const result = "The answer is " + 42; || same as const result = "The answer is " + “42”;
console.log(result); // "The answer is 42”

• NUMBER COERCION : When performing arithmetic operations, JavaScript tries to convert strings to
numbers.
const sum = "5" - “1” - 2; // "2 " is coerced to a number
console.log(Typeof sum); // Number
console.log(“12”* ”2”) // 24 string is coerced to a number in
console.log(“12”/ ”2”) // 6 string is coerced to a number
• BOOLEAN COERCION : Non-boolean values are coerced into boolean in contexts that expect a boolean, such
as if statements.

if (" ") {
console.log("This won't run");
} else {
console.log("Empty string is falsy"); // This will run
}

20 Java Script +91 9662332503 Hornbillcodingsociety@gmail.com


JavaSCRIPT

7.4 INTERVIEW QUESTIONS

• What is difference between type conversion and coercion ? (Infosys, TCS)


• Is it possible to convert string into number ?
• What is data type of NaN ? (Infosys, TCS, Wipro, Accenture, almost asked in every interview)
• What is type coercion ?
• How do you convert number to string without using constructor of Number ?

© Hornbill Coding Society +91 9662332503 Hornbillcodingsociety.com 21


CHAPTER
Equality, Boolean Logic &
8
Logical Operator

In JavaScript, equality operators are used to compare two values. There Chapter Outline
are two types of equality operators i.e., loose equality or abstract
equality, strict equality 8.1 Loose and Abstrastact
8.1 LOOSE EQUALITY/ ABSTRACT EQUALITY AND STRICT EQUALITY equality check
Abstract equality
The == operator checks for equality between two values after performing
Strict equality
type conversion if necessary, it checks for value and not type of data. It
is unpredictable and prone to give wrong results. Should be avoided. 8.2 Difference check operator

• LOOSE EQUALITY Abstract inequality

console.log(5 == '5'); // true (type coercion occurs) Strict inequality

console.log(false == 0); // true (type coercion occurs) 8.3 Boolean Logic and logical
operatot
• STRICT EQUALITY
Truth table
The === operator checks for both value and type equality without
8.4 Interview Questions
performing any type conversion.
console.log(5 === '5'); // false (different types)
console.log(false === 0); // false (different types)
This operator is more predictable and is recommended in most cases
to avoid issues caused by type coercion.
The == operator allows type conversion, while the === operator
enforces strict type comparison.

8.2 DIFFERENCE CHECK OPERATORS

JS provides two operators for checking the difference


• ABSTRACT INEQUALITY (!=) : checks if two values are equal or not.
It performs type coercion, meaning it converts the values to a
common type before comparing them.
console.log(5 != '5'); // false (values are equal after type coercion)
console.log(5 != 8); // true

• STRICT INEQUALITY(!==) : checks if two values are not equal and also
ensures their types are different. It does not perform type coercion,
so the comparison is stricter.

console.log(5 !== '5'); // true (different types)


console.log(5 !== 5); // false (same value and type)
JavaSCRIPT

8.3 BOOLEAN LOGIC AND LOGICAL OPERATOR

Boolean logic is a fundamental concept in programming that revolves around two values: true and false. In
JavaScript, Boolean logic is essential for evaluating expressions and making decisions in code. By utilizing logical
operators such as AND (&&), OR (||), and NOT (!), you can create various output combinations and control the
program's flow effectively.

AND (&&) OR (||) NOT(!)


AND TRUE FALSE OR TRUE FALSE NOT

TRUE TRUE FALSE TRUE TRUE TRUE TRUE FALSE


FALSE FALSE FALSE FALSE TRUE FALSE FALSE TRUE

📔Note: ! Operator has precedence over OR, AND


Logical operators (&&, ||, !) in JavaScript do not coerce operand types. Instead, they evaluate the
values and return one of the operands based on the operation's logic

let isAdult = true;

let hasLicense = false;

let isSober = true;

let canDrive= isAdult && isSober && hasLicense // false

8.4 INTERVIEW QUESTIONS

• What is difference between strict and loose equality check ? (Infosys, Accenture, Neosofttech, Symore, most
common question)
• What is the Boolean logic ?

© Hornbill Coding Society +91 9662332503 Hornbillcodingsociety.com 23


CHAPTER
Conditional control
Structure IF Else,
9

Switch, Ternary operator


Conditional statements are the bedrock of decision-making in Chapter Outline
programming. They allow your JavaScript code to execute different
blocks of code based on whether a specified condition is true or false. 9.1 If…else statement
The if...else structure is the most common way to implement this logic.
simple If
Condition can involve:
If…Else
• Comparison operators (==, !=, ===, !==, >, <, >=, <=) If…Else…If…Else
• Logical operators (&& for AND, || for OR, ! for NOT) Nested If…Else
• The result of a function call or a variable that holds a boolean value 9.2 Switch statement

9.1 IF ELSE STATEMENT 9.3 Statement vs Expression


9.4 Ternary operator
• SIMPLE IF : The if statement evaluates a condition, and if the
9.5 Interview Questions
condition is true, it executes the block of code inside the {} braces.
Syntax
if (condition) {
// Code to be executed if the condition is true
}

e.g., let age = 20;


if (age >= 18) {
console.log("You are eligible to vote.");
}

• IF…ELSE : The if...else statement adds an alternative block of code


that executes if the condition is false.
Syntax
if (condition) {
// Code to execute if condition is true
} else {
// Code to execute if condition is false
}

e.g., let age = 16;


if (age >= 18) {
console.log("You are eligible to vote.");
} else {
console.log("You are not eligible to vote.");
}
JavaSCRIPT

• IF…ELSE …IF…ELSE : When multiple conditions need to be checked sequentially, we use else if.
Syntax
if (condition1) {
// Executes if condition1 is true
} else if (condition2) {
// Executes if condition2 is true
} else {
// Executes if neither condition1 nor condition2 is true
}

e.g., let marks = 85;


if (marks >= 90) {
console.log("Grade: A");
} else if (marks >= 75) {
console.log("Grade: B");
} else if (marks >= 50) {
console.log("Grade: C");
} else {
console.log("Grade: F");
}

• NESTED IF…ELSE : An if...else block can be nested inside another if...else block.

e.g., let num = 10;


if (num > 0) {
if (num % 2 === 0) {
console.log("Positive Even Number");
} else {
console.log("Positive Odd Number");
}
} else {
console.log("Negative Number or Zero");
}

• LOGICAL OPERATOR IN IF… : Logical operators (&&, ||, !) can be used to combine conditions.

e.g., let isAdult = true;

let hasID = false;

if (isAdult && hasID) {

console.log("You can enter.");

} else {

console.log("You cannot enter.");

© Hornbill Coding Society +91 9662332503 Hornbillcodingsociety.com 25


JavaSCRIPT

9.2 SWITCH STATEMENT

Switch statement is an alternative way of writing if else statement The switch statement in JavaScript is used to
execute one block of code from multiple possible options based on the value of an expression. It provides a more
readable alternative to multiple if-else statements when checking the same variable against different values.
Syntax

switch(expression) {
case value1:
// Code to execute if expression === value1
break;
case value2:
// Code to execute if expression === value2
break;
default:
// Code to execute if none of the cases match
}
HOW IT WORKS
1. The expression is evaluated once.
2. The value of the expression is compared with each case.
3. If a match is found, the corresponding block of code is executed.
4. The break statement is used to stop execution after a matching case. Without break, execution will continue
to the next case (fall-through behavior).
5. The default case executes if no matching case is found.

e.g., let day = 3;


switch (day) {
case 1:
console.log("Monday");
break;
case 2:
console.log("Tuesday");
break;
case 3:
console.log("Wednesday");
break;
case 4:
console.log("Thursday");
break;
case 5:
console.log("Friday");
break;
default:
console.log("Weekend");
}

26 Java Script +91 9662332503 Hornbillcodingsociety@gmail.com


JavaSCRIPT

When to use switch instead of if

• When you have multiple conditions based on a single variable.


• When the conditions are checking for exact matches (not ranges or complex expressions).
• When you want a cleaner and more readable structure instead of multiple if-else statements.

9.3 STATEMENT vs EXPRESSION

EXPRESSIONS : An expression is a piece of code that evaluates to a value. It can be assigned to a variable, used
as an argument in a function, or appear inside another expression.

5+3 // Evaluates to 8 (Arithmetic Expression)

"Hello" + " World" // Evaluates to "Hello World" (String Concatenation)

x = 10 // Assignment Expression (returns 10)

true && false // Evaluates to false (Logical Expression)

STATEMENT : A statement is an instruction that performs an action but does not necessarily return a value.
Statements control the flow of execution in a program.
let x = 10; // Variable declaration (no value is returned)
if (x > 5) { console.log("x is greater than 5"); } // If statement (performs an action)
for (let i = 0; i < 5; i++) { // Loop statement
console.log(i);
}
function sayHello() {
console.log("Hello!"); // Function declaration (not an expression)
Js expects functions and expression in different places e.g., in template literals we can insert only expression
and not statemets `the average of 2 and 4 is ${(2+4)/2}`

Feature Statement Expression


Definition Performs an action Produces value
Can be assigned to a variable? ❌ No ✔️ Yes
Returns a value? ❌ not necessary ✔️ Always
Used inside other expressions? ❌ No ✔️ Yes

📔Note: All expressions can be statements, but not all statements are expressions.

9.4 TERNARY OPERATORS

It is also called as conditional operator provides a compact way to write conditional expressions. It's essentially
a shorthand for the if-else statement, making your code more concise and readable when dealing with simple
conditions.

Condition ? if part : else part

This is going to produce a value and that’s why it is an expression and hence we can use it in the template string

© Hornbill Coding Society +91 9662332503 Hornbillcodingsociety.com 27


JavaSCRIPT

The ternary operator is not a substitute for the if-else statement, especially when handling larger code blocks. It
is best suited for scenarios that require quick, concise decision-making.

9.5 INTERVIEW QUESTIONS

• What is the difference between the if…else statement and ternary operator ?
• What is the difference between the switch statement and if…else statement ?
• What is the difference between statement and expression ?
• What are the conditional control structure in java script ?
• Generate a programme to print whether a number is odd or even from 1 to 1000 (Most common question
generally asked to check looping skills)
• Generate a programme to check for prime number (Infosys, TCS)
• Generate a programme to see the menu of each day based on given input

28 Java Script +91 9662332503 Hornbillcodingsociety@gmail.com


Strict Mode
CHAPTER

10

Strict mode in JavaScript is a feature introduced in ECMAScript 5 (ES5) Chapter Outline


that helps developers write more secure and optimized code by
enforcing stricter parsing and error handling. It prevents common 10.1 Enable strict mode
JavaScript pitfalls and makes it easier to debug code.
Function level strict mode

10.2 Restriction in strict


10.1 ENABLE STRICT MODE
mode
To apply strict mode to an entire script, add "use strict"; at the Researved keywords
beginning of the file. || let’s introduce an intentional bug in code. Undeclared variable
This binding in global
let isAccountHolder = false;
object
const isMemberOFClub = true;
Duplicate parameter
if (isMemberOFClub) isAccountholder = true name

if (isAccountHolder)console.log("congrats"); Deleting variable and


functions
this code will simply not run since there is case mistake in “H” of the Modification to argument
isAccountholder. If we don’t use strict mode then common mistake in object
the programme are not caught like small spelling mistake of variable 10.3 Advantages of strict
name. In strict mode we get the message in console uncaught mode
RefrenceesError : isAccountHolder is not defined 10.4 Interview Questions

Note: The String “Use strict” must be the first line of the code
although comments are allowed before it as comments are
ignored in the compilation

Strict mode ensures that developer avoids the accidental errors as it


forbids developer to do certain things and it makes error more visible.

FUNCTION-LEVEL STRICT MODE: Strict mode can also be applied to


individual functions.
function myFunction() {
"use strict";

y = 5; // ❌ ReferenceError: y is not defined


console.log(y);
}
myFunction();
JavaSCRIPT

10.2 RESTRICTIONS IN STRICT MODE

• RESEARVED KEYWORDS FOR FUTURE VERSION OF JAVA SCRIPT : Strict mode reserves certain keywords for
future JavaScript versions, preventing their use as variable names even if they don’t hold the position of
reserved keywords in the current version. This ensures better forward compatibility of the code.

Restricted keywords : implements, interface, let, package, private, protected, public, static, yield.

• PREVENTS THE USE OF UNDECLARED VARIABLES : In normal JavaScript, assigning a value to an undeclared
variable creates it as a global variable. Strict mode disallows this behavior.

"use strict";
x = 100; // ReferenceError: x is not defined

• ELIMINATES this BINDING TO GLOBAL OBJECT :. In non-strict mode, if a function is called without an explicit
object, this refers to the global object (window in browsers). In strict mode, this is undefined.

"use strict";
function showThis() {
console.log(this); // undefined
}
showThis();

• PREVENTS DUPLICATE PARAMETER NAMES IN FUNCTIONS : Strict mode disallows functions with duplicate
parameter names.

"use strict";

function add(a, a) { // SyntaxError: Duplicate parameter name not allowed


return a + a;
}

• DISALLOW DELETING VARIABLE AND FUNCTIONS : In strict mode, deleting variables and functions is not
allowed.
"use strict";
let name = "Anuradha";
delete name; // ❌ SyntaxError: Delete of an unqualified identifier in strict mode.

• RESTRICT THE USE OF ARGUMENT OBJECT : Strict mode prevents modifications to the arguments object.
"use strict";
function test(arg) {
arg = 20;
console.log(arguments[0]); // 10 (in strict mode, it does not reflect the change)
}
test(10);

10.3 ADVANTAGES OF STRICT MODE


Detects Common Errors – Helps identify undeclared variables and silent errors.
Improves Performance – JavaScript engines can optimize code better in strict mode.
Prevents Unsafe Actions – Disallows dangerous operations like deleting variables.
Encourages Better Coding Practices – Helps write maintainable and error-free code.

30 Java Script +91 9662332503 Hornbillcodingsociety@gmail.com


JavaSCRIPT

10.4 INTERVIEW QUESTIONS

• What is strict mode in Java Script ?


• What are the acdvantages of strict mode in Java Script ?
• Can strict mode be applied to a specific function instead of the entire script ?
• How does strict mode affect the this keyword inside a function? (Neosoft tech, cognizant, stupa analytics)
• What are the reserved keywords in strict mode, and why are they restricted?

© Hornbill Coding Society +91 9662332503 Hornbillcodingsociety.com 31


CHAPTER
Functions in Java
11
Script
A function is a reusable block of code designed to perform a specific task. Chapter Outline
Functions are the building blocks of modularity and code reusability in
JavaScript. They encapsulate a set of instructions, making your code 11.1 Functions
more organized, readable, and maintainable
Function declaration

Function is piece of code that we can use again and again, it’s bit like a Function expression
variable but for whole chunk of code. Variable hold one value but declaration vs. expression
function hold one or more complete line of code. 11.2 Arrow function
Single line arrow function
11.1 FUNCTIONS
When to avoid
Define a function using the function keyword. Give the function a Use Case

meaningful name that follows the camelCase convention. Enclose 11.3 Interview Questions
the function's body within curly braces {}.

Function greetGuest ( ) {
console.log (“Hello Gentelman”)
}

To execute the code within a function, you call or invoke or runfunction by using
its name followed by parentheses ( )

const message = greetGuest ( ); // storing function in variable also known as


value capturing
console.log (message); // Hello Gentelman

A function not only allows you to reuse a piece of code but also can
receive data and return output. A function can be compared to a
machine in which inputs are fed, the machine processes them, and then
returns the output. Parameters of function

function makeSandwich( filling 1, filling 2, filling 3 ) {


recipe = `Sandwich with ${filling1}, ${filling2}, and ${filling3} is ready`;
return recipe; Actual value of parameter called
} as arguments
const order = makeSandwich ("Cheese", "Vegetable", "Mayonnaise");
console.log(order); // Sandwich with Cheese, Vegetable, and Mayonnaise is
ready
JavaSCRIPT

• FUNCTION DECLARATION : A function can be declared using the function keyword, similar to how variables
are defined. e.g., a function to calculate the average of two numbers can be written as follows:

function findAverage(num1, num 2){


const average = (num 1+ num 2)/2;
return average;
}
Average = findAverage(25,50); // Note: there should not be any space between the function call and ( )

• FUNCTION EXPRESSION : In a function expression, a function is assigned to a variable without giving it a


specific name. The variable itself acts as the function's name. Since this function has no explicit name, it is
referred to as an anonymous function.
Being an expression, it produces a value, which can be stored in a variable—this is what makes the variable
a function.
// Function expression assigned to a variable
const addNumbers = function (a, b) {
return a + b;
};
// Calling the function using the variable name
console.log(addNumbers(5, 10)); // Output: 15

Function Declaration vs. Function Expression

Feature Function Declaration Function Expression

Uses the function keyword to declare a Assigns an anonymous function to a variable.


Definition
named function.
Fully hoisted, meaning it can be called Not hoisted in the same way; cannot be called
Hoisting
before its definition. before its definition.

function greet() { return "Hello"; } const greet = function() { return "Hello"; };


Syntax
Always has a name. Can be anonymous (no name) or named.
Naming
Suitable for defining reusable functions in Useful for assigning functions to variables,
Use Case
a script. passing as arguments, or using in callbacks.

11.2 ARROW FUNCTION

Arrow functions were introduced in ES6 (ECMAScript 2015) as a more concise way to write functions. They
provide a cleaner syntax and change the behavior of the this keyword, making them useful in many situations,
especially for callbacks and functional programming.

const calculateTime = ( speed, distance ) => {

return time = speed/distance

© Hornbill Coding Society +91 9662332503 Hornbillcodingsociety.com 33


JavaSCRIPT

• SINGLE-LINE ARROW FUNCTION (IMPLICIT RETURN) : If the function has only one expression, the { } and
return keyword can be omitted, otherwise in multiline code return can’t be omitted

const calculateTime = ( speed, distance ) => distance/speed;

we can even omit ( ) if the only one argument is passed

const multiplicationFun = a => a * 25; // Arrow function to multiply 'a' by 25

console.log(multiplicationFun(5)); // Function call with 5 as the argument 125

• WHEN TO AVOID (advanced part more detail in following chapters)


Lexical this (No Own this) : Arrow function don’t get it’s own this keyword, instead they inherit this from
their enclosing lexical scope.
Arrow functions do not have their own arguments object. Instead, they inherit arguments from their
parent function.to access arguments we use rest parameters.
Arrow functions are not sutaible for methods in objects

• USE CASE: Arrow functions goes well with array methods like map, filter, reduce, event listners and callback
functions.

11.3 INTERVIEW QUESTIONS

• What is a function in JavaScript?


• How can functions be defined in JavaScript?
• What is the difference between a function expression and a function declaration? (one of the most common
question)
• How does a normal function differ from an arrow function? (TCS, Infosys, Stupa analytics, contrado)
• What is the difference between parameters and argument in the context of a function?

34 Java Script +91 9662332503 Hornbillcodingsociety@gmail.com


Aary Introduction
CHAPTER

12

Arrays are essential data structures that enable you to store multiple Chapter Outline
values in a single variable. While you could store a single value in a
variable, imagine needing to store millions of names in such a case. 12.1 Creating an array
Creating millions of variables would not be practical. Instead, JavaScript
Array literals
provides key data structures, such as arrays and objects, to handle such
Array constructor
situations efficiently.
12.2 Array properties and

12.1 CREATING an ARRAY methods


Accessing & modifying
Arrays can be created using two primary methods length()

• ARRAY LITERALS : The most common and concise way to create an Push()
Pop()
array.
Shift()
const team = [“Sachin”, “Virat”, “Harbhajan”, “Yuvraj”, “Dhoni”,
Unshift()
“Sehwag”, “Ganguly”, “Dravid”, “Laxman”, “Gambhir”, “Ashwin”
Concat()
]
Join()
• ARRAY CONSTRUCTOR
Slice()
const fruits = new Array(“Banana”, “Lichi”, “Apple”, “Orange”, Splice()
35, 101, true, [sweet, tangy, spicy], {sweet: ‘Banana’, tangy : IndexOf()
’orange’}) ; Includes()
console.log(fruits); // [ 'Banana', 'Lichi', 'Apple', 'Orange', ”, 35, 101, true, 12.3 Interview Questions
Array: 3, object: 2]

Arrays can hold as many values as we want and any type of value
including string, number, Boolean, object and array itself.

Note: Array is not primitive data type, it is refrence type(explained


in latter chapters)

console.log(typeof fruits) // object

12.2 ARRAY PROPERTIES AND METHODS

• ACCESSING AND MODIFYING ARRAY ELEMENTS : Array elements


are accessed and modified using their index, which starts at 0. Arrays
are 0 indexed

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


JavaSCRIPT

console.log(colors[0]); // 'red'

colors [1] = 'yellow'; // Modifies the second element

console.log(colors); // ['red', 'yellow', 'blue']

Note: Although a variable declared with const cannot be reassigned, we can observe that the value at
index 1 in the colors array is being modified. This happens because arrays are not primitive types;
they are stored as reference types. While we cannot reassign the entire array, we can update its
individual elements. Additionally, since array elements are accessed using index positions, the
order in which they are placed is crucial.

• FINDING LENGTH OF ARRAY : length returns the number of elements in the array.

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

Note: Length is not zero based so it will always show real length of the array i.e., 3 and since index is 0
based we can use this to get the last element e.g., console.log(team[team.length – 1] ) // Ashwin

• PUSH( ): Adds one or more elements to the end of the array.

colors.push('purple');
console.log(colors); // ['red', 'yellow', 'blue', 'purple']

• POP( ) : Removes the last element from the array and returns it.

const lastColor = colors.pop( );


console.log(lastColor); // 'purple'

console.log(colors); // ['red', 'yellow', 'blue']

• SHIFT( ) : Removes the first element from the array and returns it.

const firstColor = colors.shift( );


console.log(firstColor); // 'red'

console.log(colors); // ['yellow', 'blue']

• UNSHIFT( ) : Adds one or more elements to the beginning of the array.

colors.unshift('green');
console.log(colors); // ['green', 'yellow', 'blue']

• CONCAT( ) : Combines two or more arrays into a new array.

const moreColors = ['orange', 'pink'];


const allColors = colors.concat(moreColors);
console.log(allColors); // ['green', 'yellow', 'blue', 'orange', 'pink']

• JOIN( ) : Joins all elements of the array into a single string, separated by a specified separator.

const colorString = colors.join('&');

36 Java Script +91 9662332503 Hornbillcodingsociety@gmail.com


JavaSCRIPT

console.log(colorString); // 'green&yellow&blue'

• SLICE( ) : Returns a shallow copy of a portion of the array into a new array object.(shallow copy explained in
following chapter)

array.slice(startIndex, endIndex) // startIndex (optional) – The index where the extraction begins
(inclusive). If omitted, it starts from index 0.
endIndex (optional) – The index where the extraction stops (exclusive). If omitted, it extracts until the
end of the array.
Returns a new array with the extracted elements.

const subArray = colors.slice(1, 3); // first argument index – start , second argument index - not inclusive

console.log(subArray); // ['yellow', 'blue']

• SPLICE( ): Changes the contents of an array by removing or replacing existing elements and/or adding new
elements

startIndex (required) – The index where changes begin.


deleteCount (optional) – Number of elements to remove. If 0, no elements are removed.
item1, item2, ..., itemN (optional) – Elements to insert at startIndex.

colors.splice(1, 1, 'purple', 'orange');

console.log(colors); // ['green', 'purple', 'orange', 'blue']

• IndexOf( ) : To know at which position certain element exist, if element dosen’t exit it returns -1

console.log(colors.indexOf(‘blue’)); // 2

console.log(colors.indexOf(‘black’)); // -1

• includes ( ) : It dosen’t return index rather it return the true or false if element is part of array. Here strict
equality chek is done. Included in ES6 ES2015

console.log(colors.includes (‘magenta’)); // false

console.log(colors.indexOf(‘red’)); // true

12.3 INTERVIEW QUESTIONS

• What is an array?
• What types of data can an array store?
• How does the splice method differ from slice? (asked in almost all the interview)
• What is the difference between indexOf() and includes()?
• How do pop and shift differ in functionality? (asked in almost all the interview)
• What is the distinction between push and unshift?

© Hornbill Coding Society +91 9662332503 Hornbillcodingsociety.com 37


CHAPTER

13 Introduction to Object

In JavaScript, an object is a collection of key-value pairs, where keys are Chapter Outline
strings (or Symbols) and values can be any data type, including
functions. Objects allow us to store and manipulate structured data. 13.1 How Object is different
13.2 Create objects
13.1 HOW OBJECT IS DIFFERENT
Object literals
Till now we we saw array data structure to store multiple value e.g., 13.3 Accessing object

const sachinArray = [ properties


Dot notation
"Sachin", // First name
Bracket notation
"Tendulkar", // Last name
13.4 Adding properties to
"Batsman", // Role in the team
object
100, // Centuries scored
Dot notation
1986, // Debut year
Bracket notation
2013, // Retirement year
13.5 Object methods
"Master Blaster" // Title
13.6 Interview Question
];
While arrays allow us to store multiple values, they have a limitation—
we cannot assign meaningful names to each element. In the case of
sachinArray, we can interpret what each value represents because
Sachin Tendulkar is well-known. However, this approach is not practical
for every situation.
Limitations of Arrays:
• Array elements can only be accessed by their index number.
• There is no built-in way to associate a value with a descriptive name.

To overcome this limitation, JavaScript provides objects, a data structure


that stores data in key-value pairs. With objects, we can assign
meaningful names (keys) to each value, making the data more readable
and manageable.

13.2 CREATE OBJECTS

Objects are one of the fundamental data types in JavaScript and are
classified as reference types rather than primitive types. Along with
arrays, functions, and dates, they fall under the category of reference
types
JavaSCRIPT

Note: Rules to follow while defining keys

• Keys must be string or symbols, number Boolean and other data types automatically converts
to string.

• Must not be a researved keyword, cannot contain spaces or special characters (except _ and $).

• If a key includes spaces, special characters, starts with a number, or is dynamic, it must be
enclosed in square brackets ([ ]).

• Object keys are case-sensitive

• In object literals, if duplicate keys exist, the last defined key overrides the previous ones.

• CREATE ARRAY USING OBJECT LITERALS SYNTAX


const sachinObj = {
firstName : "Sachin" ,
lastName : "Tendulkar",
roleInTeam : "Batsman",
centuriesScored : 100,
debutYear : 1986,
retirementYear : 2013,
title : "Master Blaster",
partOfTeam : [‘Mumbai’, ‘Mumbai Indian’, ‘Team India’]
};
We use objects to store related data or group together variables that logically belong to the same entity, such as
Sachin's properties.

Note: In an object, the order of properties does not matter since values are accessed using keys rather
than indexes. Unlike arrays—where order is crucial because elements are retrieved by their
position—objects store data in key-value pairs, and their keys are typically arranged in alphabetical
order when accessed programmatically.

We use arrays for structured, order-dependent data, whereas objects are ideal for unstructured data that need
to be labeled and retrieved using specific names.
There are multiple ways to create arrays, such as using the Array constructor, Object.create(), constructor
functions, and ES6 classes. We will explore these methods in detail in the upcoming chapters.

13.3 ACCESSING OBJECT PROPERTIES

There are three ways in which the properties of the objects can be accessed dot notation and bracket notation
and for…in loop out of which we are going to discuss dot notation and bracket notation and for…in the following
chapters
• DOT NOTATION : Always use it when no value needs to be returned, as it results in cleaner code.

console.log(SachinObj.firstName); // Sachin

• BRACKET NOTATION : In JavaScript, bracket notation enables access to object properties using dynamic keys
(expressions that evaluate to property names), while dot notation requires a fixed, predefined key.

© Hornbill Coding Society +91 9662332503 Hornbillcodingsociety.com 39


JavaSCRIPT

Note: We must enclose the key in quotes when using bracket notation. Additionally, we can pass an
expression inside the brackets that evaluates to a valid key:

e.g., console.log(sachinObj['lastName']); // Sachin

const nameKey = 'Name';

console.log(sachinObj['first' + nameKey]); // Output: Sachin

console.log(sachinObj['last' + nameKey]); // Output: Tendulkar

However, this does not work with dot notation because JavaScript treats 'last' + nameKey as a string and does
not dynamically evaluate it as a key:

console.log(sachinObj.'last' + nameKey); // Invalid Syntax

Using User Input with Bracket Notation

const interestedIn = prompt( "What do you want to know about Sachin? (firstName, lastName, debutYear,
retirementYear, roleInTeam, centuriesScored, title, partOfTeam)" );

console.log(sachinObj[interestedIn]); // Valid: Uses dynamic key

prompt() allows users to enter a property name, which is taken as a string.


Bracket notation is necessary here because interestedIn is a variable whose value needs to be evaluated as
a key.
Dot notation cannot be used in this case, as sachinObj.interestedIn would look for a property literally
named "interestedIn", which does not exist.
This method makes objects more flexible by allowing properties to be accessed dynamically.

13.4 ADDING PROPERTIES TO OBJECT

we have dot notation and bracket notation to add data to the object.

• DOT NOTATION
sachinObj.car = ‘Ferrari’ // adds property car to sachin object
• BRACKET NOTATION : Bracket notation ([]) allows adding a new property dynamically. It also allows
expression to be passed as key
sachinObj[‘isFarmOwner’] = true // adds a Boolean property to the sachin object

13.5 OBJECT METHODS

In JavaScript, we can store objects within other objects. Since functions are also a type of object, we can include
functions as properties inside an object.

const sachin = {
firstName : "Sachin" ,
lastName : "Tendulkar",
roleInTeam : "Batsman",
centuriesScored : 100,

40 Java Script +91 9662332503 Hornbillcodingsociety@gmail.com


JavaSCRIPT

debutYear : 1986,
retirementYear : 2013,
title : "Master Blaster",
partOfTeam : [‘Mumbai’, ‘Mumbai Indian’, ‘Team India’],
totalYearPlayed : function(retirementYear, dubutYear){

return retirementYear – dubutYear;


}
}

We can even access the property using dot notation and bracket notation.

console.log(sachinObj.totalYearPlayed(2013 -1968)); // 27

console.log(sachinObj[totalYearPlayed(2013 -1968)]); // 27

Note: Any function attached to object is called as method. And only function expression works here in
object not the function declaration

Every JS method gives us access to special keyword called this. This method or keyword is equal to the object on
which it is called. In other words it is the object calling method. It points to the object in which method is
called.

const sachinObj = {
firstName: "Sachin",
lastName: "Tendulkar",
roleInTeam: "Batsman",
centuriesScored: 100,
debutYear: 1986,
retirementYear: 2013,
title: "Master Blaster",
partOfTeam: ["Mumbai", "Mumbai Indian", "Team India"],
totalYearPlay: function() {
this.yearsPlayed = this.retirementYear - this.debutYear; // storing value in variable to reduce
computation cost

return this.yearsPlayed; // Added return statement even


}
};

console.log(sachinObj.totalYearPlay( )); // Output: 27 calling method is essential to initialise the yearsPlayed property

console.log(sachinObj.yearsPlayed); // Output: 27 Checking the newly added property

In the example, sachinObj is invoking the method. Therefore, whatever appears before the dot (i.e., sachinObj)
is the entity calling the method. As a result, within the method, this refers to sachinObj.

© Hornbill Coding Society +91 9662332503 Hornbillcodingsociety.com 41


JavaSCRIPT

13.6 INTERVIEW QUESTIONS

• What is an object in JavaScript?


• How do you create an object in JavaScript?
• What are the rules for declaring the keys of object ?
• What is the difference between an object and an array in JavaScript? (Infosys, contrado, level9trips, TCS,
Mindtree)
• What is the significance of the this keyword in an object method? (contrado, level9trips, stupa anlytics)

42 Java Script +91 9662332503 Hornbillcodingsociety@gmail.com


CHAPTER
Looping Control
14 Structure
5

Looping control structures in JavaScript allow you to execute a block of Chapter Outline
code repeatedly. This is useful when you need to perform the same
action multiple times, iterate over arrays, or process data in a structured 14.1 For loop
way. Here's a breakdown of the main looping structures 14.2 While loop
14.1 FOR LOOP Infinite loop
14.3 Do while loop
The for loop is the most common looping structure. It's best used when
14.4 For…in loop
you know the exact number of iterations needed.
14.5 For…of loop
SYNTAX 14.6 forEach loop
for (initialization; condition; increment/decrement) { 14.7 Loop control statement
// Code to be executed Brake statement
} Continue statement

• Initialization : This statement is executed once at the beginning of 14.8 Nested loop
the loop. It's typically used to declare and initialize a counter variable. 14.9 Choose right loop
• Condition : This expression is evaluated before each iteration. If it's 14.10 Interview Question
true, the loop continues. If it's false, the loop terminates.
• Increment/Decrement : This statement is executed after each
iteration. It's typically used to update the counter variable.

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

console.log("Iteration number: " + i);


}

let i = 1; Initialization (variable i is set to 1).


i <= 5; → Condition (loop runs until i is less than or equal to 5).
i++ → Increment (increases i by 1 after each iteration).

14.2 WHILE.. LOOP

The while loop executes a block of code as long as the specified


condition is true. This loop is used where number of itration is not known
in advanced. e.g., - rolling a dice till we get six on top face, now it may
occoure in the first iteration or may take 1000 or even more there is no
certainty in getting six.
JavaSCRIPT

SYNTAX
while (condition) {
// Code to be executed
}

EXAMPLE

let dice = Math.trunc(Math.random() * 6) +1; // math.random() generate random number between 0 and 1, *6 make
it 0 to 5.999 and +1 make it till six, and math.trunc() delete the decimal part
while (dice !== 6) { // Run the loop until dice rolls a 6
console.log(`You rolled ${dice}`);
// Roll the dice again
dice = Math.trunc(Math.random() * 6) + 1;
if (dice === 6) console.log("Loop is about to end");
}

The loop keeps rolling the dice until 6 appears.


It prints "You rolled X" for each roll.
When 6 is rolled, "Loop is about to end" is printed, and the loop stops.
INFINITE LOOP
An infinite loop is a loop that runs indefinitely without terminating because it’s exit condition is never met. This
can happen due to incorrect logic, missing update statements, or an always-true condition.

for (let i = 1; i > 0; i++) {


console.log(i); // This will run forever because i is always increasing
}
// here console will log infinite number as there is errenous codition which does not break the loop and it result into
braking down of the browser

14.3 DO…WHILE LOOP

The do...while loop is similar to the while loop but ensures the code runs at least once before checking the
condition

SYNTAX

do {
// Code to be executed in each iteration

} while (condition);

EXAMPLE
let dice;
do {

dice = Math.trunc(Math.random() * 6) + 1; // Generate a random number between 1 and 6


console.log(`You rolled a ${dice}`);
} while (dice !== 6); // Keep rolling until we get a 6
console.log("Loop has ended because we rolled a 6!");

44 Java Script +91 9662332503 Hornbillcodingsociety@gmail.com


JavaSCRIPT

The loop executes once before checking the condition because condition is checked after execution of code.
If dice != 6 is true, it continues executing.
If the condition is false, it stops after the first execution.

14.4 FOR…IN LOOP

The for...in loop is used to iterate over the enumerable properties (keys) of an object. It is primarily used for
iterating over object properties but can also be used with arrays (though not recommended).
SYNTAX
for (let key in object) {

// Code to be executed
}

EXAMPLE

const student = { name: "John", age: 20, course: "JavaScript" };


for (let key in student) {
console.log(key + ": " + student[key]);
}

key takes the property names (name, age, course).


student[key] gives the corresponding values (John, 20, JavaScript).

14.5 FOR…OF LOOP

The for...of loop iterates over the values of an iterable object (like arrays, strings, maps, sets, etc.).

for (const element of iterable) {

// Code to execute
}

EXAMPLE

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


for (const color of colors) {
console.log(color);
}

If we want to ectract the index in the array

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

for (const [index, color] of colors.entries()) {

console.log(`Index: ${index}, Color: ${color}`);

© Hornbill Coding Society +91 9662332503 Hornbillcodingsociety.com 45


JavaSCRIPT

14.6 FOR EACH LOOP

The forEach method is a higher-order function that requires a callback function to define what actions should
be performed on each element of an array. When forEach loops over an array, it executes the provided callback
function once for each element. During each iteration, the forEach method automatically passes the current
element of the array as an argument to the callback function.

A key difference between forEach and for...of is that you cannot break out of a forEach loop. The continue and
break statements do not work within forEach, meaning it always iterates through the entire array. In contrast,
the for...of loop allows the use of break and continue, making it more suitable when you need to exit the loop
early or skip specific iterations.

let students = ["Alice", "Bob", "Charlie", "David"];

// Using forEach to iterate over the array


students.forEach(function(student, index) {
console.log(`Student ${index + 1}: ${student}`);
});

14.7 lOOP CONTROL STATEMENT

• BREAK STATEMENT : The break statement is used to exit a loop prematurely OR Terminates the loop
immediately.

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


if (i === 5) {
break; // Loop stops when i = 5
}
console.log(i);
}
// output : 1 2 3 4 loop terminates when i = 5

• CONTINUE STATEMENT : The continue statement Skips the current iteration and proceeds to the next one.

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

if (i === 3) {

continue; // Skips iteration when i = 3

console.log(i);

// output : 1 2 4 5 number 3 is skipped.

Note: Break terminates the the whole loop not just current iteration, whereas continue skips the iteration
where condition is satisfied and move on to next iteration.

46 Java Script +91 9662332503 Hornbillcodingsociety@gmail.com


JavaSCRIPT

14.9 NESTED LOOPS

We can insert any piece of code inside loop insde so we can insert another loop inside a loop as loop itself is a
piece of code. It’s just that we have to use different variable name for initialisation in the both loop.

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


for (let j = 1; j <= 3; j++) {
console.log(`i = ${i}, j = ${j}`);
}
}
// output :
i = 1, j = 1
i = 1, j = 2
i = 1, j = 3
i = 2, j = 1
i = 2, j = 2
i = 2, j = 3
i = 3, j = 1
i = 3, j = 2
i = 3, j = 3

Each iteration of the outer loop executes the inner loop completely.

14.9 CHOOSE A RIGHT LOOP

• Use for when you know the number of iterations.


• Use while or do...while for loops with an unknown number of iterations.
• Use for...in for iterating over object properties.
• Use for...of for iterating over iterable objects like arrays and strings.

14.10 INTERVIEW QUESTIONS

• What is the difference between break and continue in loops? (Infosys, TCS, Wipro)
• How can you exit a loop prematurely in JavaScript?
• How would you skip a particular iteration inside a loop?
• Can a for loop be replaced by a while loop? If yes, how?
• How do nested loops work? Provide an example.
• What is an infinite loop? How can you avoid it?
• How does forEach () compare to traditional loops like for and while? (Infosys, TCS, Contrado, Stupa analytics,
cognizant, Atos, delloite)

© Hornbill Coding Society +91 9662332503 Hornbillcodingsociety.com 47


CHAPTER
Java Script
15
Interaction with DOM

Java Script interacts with the web page to bring dynamism in the page Chapter Outline
this is called as DOM manipulation.

15.1 What is DOM


15.1 WHAT IS DOM
15.2 Interview Questions
• The Document Object Model (DOM) is a structured representation
of an HTML document. It acts as a bridge between the HTML
document and JavaScript, allowing JavaScript to access and
manipulate HTML elements, attributes, and styles dynamically. With
the DOM, we can modify text content, update attributes, and even
change CSS styles from JavaScript.
• The DOM is automatically created by the browser as soon as a page
loads. The browser generates a tree-like structure (DOM tree) that
represents the document's elements hierarchically. Each HTML
element corresponds to an element node in the DOM tree, and
JavaScript can interact with these nodes to modify the page
dynamically.
• The DOM always starts with the document object at the top of the
hierarchy. This document object serves as the entry point for
accessing and manipulating the DOM. in JavaScript, we can use e.g.,
document.querySelector(".header");
• This line demonstrates that the querySelector method is available
on the document object, reinforcing the idea that the document
object is our gateway to the DOM.
• The first child element of the document is typically the <html>
element since it is the root element in an HTML document.
• All the methods and properties we use to manipulate the DOM are
not actually part of JavaScript itself. Instead, they belong to Web
APIs, which are provided by the browser. These APIs allow
JavaScript to interact with the browser environment.
• Besides the DOM, there are other useful Web APIs, such as:
• Fetch API – for making HTTP requests.
• Timer APIs (setTimeout, setInterval) – for handling time-based
events.
JavaSCRIPT

• These APIs enhance JavaScript’s capabilities and allow us to create interactive and dynamic web applications.
Below is given the sample code and DOM tree it generates.

<!DOCTYPE html>

<html>

<head>

<title>Simple DOM Example</title>

</head>

<body>

<section>

<h1 id="heading">Hello, World!</h1>

</section>

<section>

<p class="text">This is a paragraph.</p>

<button onclick="changeText()">Click Me</button>

</section>

</body>

</html>

Document

Element <Head> Element <Body>

ELEMENT ELEMENT
Element <Title> <Section> <Section>

ELEMENT
Text “A single page” <P> ELEMENT ELEMENT
<P> <Button>

Text Text
“This is paragraph” “Click me”

15.2 INTERVIEW QUESTIONS

• What is DOM ?
• How connection between JS and HTML is established ?

© Hornbill Coding Society +91 9662332503 Hornbillcodingsociety.com 49


How Js Works
CHAPTER

16

JS is high level, prototype based, object oriented, multiparadigm, Chapter Outline


interpreted, Just in time compiled dynamic, single threaded, garbage-
collected programming language with first class function and a non 16.1 Definition brakedown
blocking event loop concurrency model.
High level

Garbage collected
16.1 DEFINITION BREAKDOWN
Interpreted JIT
• HIGH LEVEL : Every program running on your computer requires
Multiparadigm language
hardware resources, such as memory and the CPU, to function. In
Prototype based OOPA
low-level languages like C, developers must manually manage these
First class function
resources, such as allocating memory for new variables. In contrast,
high-level languages like JavaScript and Python handle resource Dynamically typed

management automatically through built-in abstractions, Non Blocking event loop

simplifying development. While these features make high-level 16.2 JS runtime


languages easier to use, the trade-off is performance—since manual Compilation vs interpreted

memory management in C allows for greater efficiency, making it 16.3 Java Script engine
inherently faster than languages that handle it automatically. 16.4 Java Script runtime

• GARBAGE COLLETCTED : One powerful feature that simplifies 16.5 How JS exactly works

memory management for developers is garbage collection. This Execution context


Global execution context
built-in algorithm in the JavaScript engine automatically removes
Call Stack
old, unused objects from memory, preventing unnecessary clutter.
Component of execution
Think of it as an automated cleaning process that ensures efficient
context
memory usage, eliminating the need for manual intervention in our
Execution context in arrow
code. function
• INTERPRETED JUST IN TIME COMPILED : A computer's processor 16.6 Interview Questions
understands only zeros and ones—known as machine code. Since
writing programs directly in machine code is impractical, we use
human-readable languages like JavaScript, which act as abstractions
over machine code. However, this code must be translated into
machine code before execution, a process handled through
compilation or interpretation. Every programming language
requires this translation, as writing machine code manually is not
feasible. In JavaScript, this process occurs within the JavaScript
engine.
JavaSCRIPT

• MULTIPARADIGM LANGUAGE : JavaScript is a multi-paradigm language that supports procedural, object-


oriented, and functional programming. It also accommodates both imperative and declarative
programming styles, offering flexibility in coding approaches.

• PROTOTYPED BASED OBJECT ORIENTED APPROACH : JavaScript follows a prototype-based object-oriented


programming (OOP) approach, which is different from class-based OOP found in languages like Java or C++
In JavaScript, objects inherit directly from other objects (blueprint) using a special mechanism called
prototypal inheritance. Instead of using classes to define blueprints, JavaScript allows objects to inherit
properties and methods from a prototype object.

• FIRST CLASS FUNCTION : Meaning that functions are treated just as regular variables. So, we can pass
functions into other functions and we can even return functions from functions. And this is extremely
powerful because it allows us to use a lot of powerful techniques

• DYNAMICALLY TYPED : in JavaScript, we don't assign data types to variables. Instead, they only became
known when the JavaScript engine executes our code. Also, the type of variables can easily be changed as
we reassign variables. And this is basically what dynamically-typed means. In JavaScript, variables are not
assigned specific data types. Instead, their types are determined at runtime when the JavaScript engine
executes the code. Additionally, a variable's type can change dynamically as it is reassigned. This flexibility is
what defines JavaScript as a dynamically-typed language.

• NON BLOCKING EVENT LOOP : JavaScript uses a single-threaded concurrency model, meaning it can
execute only one task at a time. To handle multiple tasks efficiently without blocking execution, it relies on
the event loop, which offloads long-running operations (like fetching data) to the background and
reintegrates them once complete. This enables non-blocking behavior, ensuring smooth performance
despite JavaScript's single-threaded nature.

16.2 JS RUNTIME

JS engine is simply a programme that executes the JS code. Every browser has it’s own JS engine as given in
the following table.

Browser Engine
V8
Google chrome / Node JS
V8
Microsoft edge
V8
Opera
Spider Monkey
Mozella firefox
Chakra
Internet explorer
Java Script core
Apple Safari

Any JS engine contains a call stack and a heap. Call stack is where a code is executed using something called
execution context, and the heap is the unstructured memory pool which stores all the object that our
application needs

© Hornbill Coding Society +91 9662332503 Hornbillcodingsociety.com 51


JavaSCRIPT

Functionalities provided to engine,


accessible in windows object
Java Script Engine
Web APIS

DOM Fetch API


Heap/Unstructured Call Stack/Code
memory pool Timer Others
execution

Essential for non blocking concurrency


Event Loop model

Callback Queue

Callback Function Data fetching from DB


Objects that our web
application needs
Others

Code must be converted into machine code before execution. To understand this process, we first need to
differentiate between compilation and interpretation. Since a computer's processor only understands binary (0s
and 1s), every program must be translated into machine code, which is done through either compilation or
interpretation.

Compilation Interpretation
There is an interpreter which runs through the
The entire code is converted into machine code at
sourse code and and executes it line by line
once and written into binary file that can be executed
by any computer later on.
It involves only one step process
Two step process first compilation and in second step
execution
The code is read and executed all in same time,
Executinon happens way after the compilation
conversion of code into machine code takes place just
before execution in real time and not ahade of time

Disadvantage is interpreted languages are much


Relatively fast
slower

Step 1
Step 1 Step 2 Source code Programme Execution
Portable File Execution of code line by line
Source code Programme Execution
Compilation Machine code Execution

Execution can happen Code yet not converted in machine code


way after the compilation

The distinction between compiled and interpreted languages isn't so clear-cut anymore. JavaScript uses a
combination of both approaches to optimize performance, a technique known as Just-In-Time (JIT)
Compilation.

JIT compilation translates the entire code into machine code all at once, but instead of generating a portable file,
it executes the code immediately. While it still follows a two-step ahead-of-time compilation process, the key
difference is that there is no separate file to run—execution happens on the fly.

52 Java Script +91 9662332503 Hornbillcodingsociety@gmail.com


JavaSCRIPT

16.3 JAVA SCRIPT ENGINE

When JavaScript code enters the engine, the first step is parsing, which involves reading and analyzing the code.
During this process, the code is converted into a structured data representation called the Abstract Syntax Tree
(AST). This is done by breaking the code into meaningful components, such as const or function, and organizing
them into a tree-like structure. Parsing also checks for syntax errors, and the resulting AST is later used to
generate machine code.

A common question is whether the AST and the DOM tree are related. The answer is no—they serve different
purposes and have no direct connection.

Step 2 : The Abstract Syntax Tree (AST) is compiled into machine code, which is then executed immediately.

Step 3 : The machine code runs within the JavaScript call stack, Modern JavaScript engines use advanced
optimization strategies to enhance performance. Initially, they generate an unoptimized version of machine
code to begin execution as quickly as possible. Meanwhile, in the background, the code undergoes continuous
optimization and recompilation while the program is still running. Each optimized version seamlessly replaces
the previous one without interrupting execution.

This process is what makes modern engines like V8 exceptionally fast. Parsing, compilation, and optimization
occur in dedicated threads within the engine, separate from the main thread , which executes JavaScript in
the call stack. While different engines may implement this process differently, this is the core concept behind
Just-In-Time (JIT) compilation in JavaScript.

CODE

Compilation happens in a special


thread that is inaccessible from
the code Parsing

AST
Compilation
Just in time compilation

Optimization
Execution takes
Execution place in call stack

During Execution

16.4 JAVA SCRIPT RUNTIME

A JavaScript runtime is like a container that includes everything needed to run JavaScript, especially in a browser.
At its core, it has a JavaScript engine, which is essential for executing JavaScript code. However, the engine alone
isn’t enough—it also needs Web APIs (e.g., DOM, timers, console.log), which are provided by the browser but
are not part of the JavaScript language itself. JavaScript accesses these APIs via the global window object.

Another key component is the callback queue, which stores callback functions (e.g., event handlers for button
clicks). When an event occurs, its callback function is placed in the queue. Once the call stack is empty. This
mechanism ensures JavaScript's non-blocking concurrency model.

© Hornbill Coding Society +91 9662332503 Hornbillcodingsociety.com 53


JavaSCRIPT

JavaScript isn’t limited to browsers—it also runs in Node.js. Unlike browsers, Node.js lacks Web APIs and
instead provides C++ bindings and a thread pool to handle asynchronous tasks.

16.5 HOW JS EXACTLY WORKS

Once JavaScript code finishes compiling, it enters execution. The first step is the creation of a global execution
context, where top-level code (code outside any function) runs.

Functions and variable declarations are registered, but function


Compilation
execution only occurs when they are called.

What is an Execution Context?


Creation of global
An execution context is an environment where JavaScript code execution context(Top
runs, containing all necessary data such as variables, function and level code)

arguments. Think of it like a pizza box: the pizza represents the


Execution of top-
JavaScript code, while the box (execution context) holds level code (inside
everything needed to serve it, like cutlery (variables) and a receipt global EC)

(arguments).
Execution of
function and
The Global Execution Context waiting for callback
In every JavaScript program, there is always one global execution
context, which serves as the default environment where top-level code executes. Once this code completes,
functions begin execution, each creating its own execution context. This applies to methods as well, since they
are simply functions attached to objects.

The Call Stack Execution context


Execution contexts are managed using the call stack, which
organizes function execution order. The currently running
function's execution context is placed at the top of the stack. Variable environment
• Let, const, var declaration
When a function completes, its context is removed, and
• Functions
execution returns to the previous one. The engine waits for • Argument object - Not
available in arrow function
callback functions (e.g., event listeners), which are provided by
the event loop.
Scope Chain
Components of an Execution Context
Each execution context consists of:
This Keyword
Not available in arrow
1. Variable Environment – Stores variables, function function

declarations, and the special arguments object (containing


parameters passed to the function).

2. Scope Chain – Maintains references to variables outside the function for access to outer scopes.

3. this Keyword – Refers to the calling context, except in arrow functions, which inherit this from their closest
regular function.

54 Java Script +91 9662332503 Hornbillcodingsociety@gmail.com


JavaSCRIPT

These components are initialized in the creation phase, which occurs before execution.

Execution Context in Arrow Functions


Unlike regular functions, arrow functions do not have their own arguments object or this keyword. Instead,
they inherit these from their nearest non-arrow function.

By managing execution contexts through the call stack, JavaScript ensures structured and efficient function
execution.

16.6 INTERVIEW QUESTIONS

• What are the key characteristics of JavaScript as a programming language?


• Can you explain the role of the JavaScript engine in executing JavaScript code? (Infosys)
• What is the difference between the call stack and the heap in a JavaScript engine? (Infosys, TCS, Contrado,
Pwc, Cognizant)
• How does Just-In-Time (JIT) Compilation work in JavaScript, and how does it differ from traditional
compilation and interpretation? (Atos)
• What is an execution context in JavaScript, and how does it relate to the execution of functions?
• Can you explain the concept of the global execution context and how it differs from other execution
contexts?
• What are the components of an execution context, and what role do each of them play during the execution
of JavaScript code? (asked in almost all adavanced level interview)
• How do arrow functions behave differently from regular functions in terms of this and the arguments object?
• In JavaScript, what is the purpose of the event loop, and how does it handle callback functions from the
callback queue? (asked in almost all adavanced level interview)

© Hornbill Coding Society +91 9662332503 Hornbillcodingsociety.com 55


CHAPTER
Inside Mechanism of
17
JavaScript

JavaScript is a single-threaded language, meaning it can execute only Chapter Outline


one task at a time. To manage the execution of code efficiently,
JavaScript follows a structured process involving execution contexts and 17.1 Code compilation and
the call stack, event loop. These concepts form the foundation of how execution context creation
JavaScript runs code, handles function calls, and manages memory. What is execution context
Execution context for function
17.1 CODE COMPILATION AND EXECUTION CONTEXT CREATION call

Once our JavaScript code has been successfully compiled, it is ready to Call stack managing execution
context
be executed. The first step in execution is the creation of a global
17.2 Scope chain
execution context for the top-level code—which refers to any code that
Scope
exists outside of functions. Functions themselves are not executed
Scope of variable
immediately; they only run when they are explicitly called.
17.3 Scope chain vs Call Stack
• WHAT IS AN EXECUTION CONTEXT? 17.4 Interview Questions
An execution context is the environment in which JavaScript code is
executed. Think of it as a container that holds all the necessary
information for the code to run, such as:
1. Local variables
2. Function arguments
3. References to outer variables (scope chain)
Every JavaScript project, regardless of its complexity, starts with a
single global execution context. This remains the default execution
context until functions begin to execute.
• EXECUTION CONTEXT FOR FUNCTION CALLS
Each time a function is called, JavaScript creates a new execution
context specifically for that function. This applies to methods as
well since methods are simply functions attached to objects. The
function execution context contains all the information needed to
execute that function.
Once all function calls have been completed, the JavaScript engine
waits for callback functions (such as those associated with event
listeners like click events) to arrive. These callbacks are handled by
the event loop, which continuously checks and processes them as
they become available.
JavaSCRIPT

Each execution context consists of three main components:


1. Variable Environment – Stores all declared variables and function declarations, along with a special
arguments object (which contains the arguments passed to the function).
2. Scope Chain – A reference to variables from parent execution contexts, allowing functions to access variables
outside their own scope.
3. this Keyword – Refers to the object that the function belongs to (context-dependent).
When a function is called, the execution context undergoes a creation phase, where these components are
initialized before the actual execution begins.

Note : Arrow functions behave differently, Unlike regular functions, arrow functions do not have their own
arguments object or this keyword. Instead, they inherit these from the nearest parent function.

• CALL STACK – MANAGING EXECUTION CONTEXTS

To keep track of function execution order, JavaScript uses the call stack . The call stack operates as
follows:
When a function is called, its execution context is pushed onto the stack.
The function on top of the stack is the one currently executing.
When a function completes execution, its context is popped off the stack, and control returns to the
previous context.
This process continues until the entire program finishes executing. Only after all functions have run and
returned does the global execution context get removed from the call stack, signaling the end of program
execution.
All these concepts can be understood with the following example.

console.log("Start");

function processOrder(orderId) {
console.log(`Processing order ${orderId}`);

setTimeout(() => {
console.log(`Order ${orderId} is ready!`);
}, 2000);

payment(orderId);
}

function payment(orderId) {
console.log(`Payment successful for order ${orderId}`);
}

processOrder(101);

console.log("End");

© Hornbill Coding Society +91 9662332503 Hornbillcodingsociety.com 57


JavaSCRIPT

• Execution Context Creation:


1. The Global Execution Context (GEC) is created.
2. console.log("Start") is executed.
3. processOrder(101) is called, so its Execution Context is created and pushed onto the Call Stack.
• Call Stack Operations:
1. Inside processOrder(101), console.log("Processing order 101") is executed.
2. setTimeout(...) is encountered. Since it's an asynchronous operation handled by the Web API, it is
offloaded to the callback Queue and does not block execution.
3. The payment(101) function is called, pushing it onto the Call Stack.
4. console.log("Payment successful for order 101") is executed.
5. payment(101) finishes execution and is popped from the Call Stack.
6. processOrder(101) completes execution and is popped from the Call Stack.
• Event Loop & Callback Queue:
1. console.log("End") executes.
2. The Call Stack is now empty.
3. The Event Loop picks the setTimeout callback (console.log("Order 101 is ready!")) from the Callback
Queue and pushes it to the Call Stack for execution after 2 seconds.

17.2 SCOPE CHAIN

The scope chain is a fundamental concept in JavaScript that governs how the engine looks up variables and
identifiers in your code. i.e., it simply answers the question where can we access a certain variable and where
not?

In Java script we have lexical scoping i.e., way the function and variables are accessed are defined by the
placement of function and blocks in the code e.g., a function that is written inside another function has access
to the variables of the parent function

Scope : space or environment in which certain variable are declared (variable environment in case of function)
there is global scope, function scope and block scope.

Scope of variable : region of code where certain variable is accessed.

Global scope Function scope (local scope) Block Scope(ES6)


• Variable are accessible only
• top level code which is not • Each function creates the
inside block (block scoped)
within any code block or scope of it’s own and variable
• This only applies to the
function declared inside of that
variable declared with the let
• variable declared in the globle function scope are accessible
and const variable
scope are accessiable inside that function
• Fuction declared in the block
everywhere in the programme • Same as functions variable
are also block scoped (but only
environment
in the strict mode)

Traditionally, only functions created scopes in JavaScript. However, starting from ES6, blocks (i.e., everything
enclosed within curly braces {}), such as if statements and for loops, also create their own scopes.

58 Java Script +91 9662332503 Hornbillcodingsociety@gmail.com


JavaSCRIPT

Similar to function scope (local scope), variables declared inside a block are accessible only within that block and
not outside. However, the key distinction is that variables declared using let and const are restricted to block
scope, whereas variables declared with var are not.

Any variable declared with var is scoped to either the enclosing function or the global scope, rather than being
restricted to the block in which it was declared. This is why var is considered as function scoped.

Lastly, starting from ES6, all functions are block-scoped when running in strict mode.
let globalVar = "I am in global scope";

function outerFunction() {
let outerVar = "I am in outer function";

function innerFunction() {
let innerVar = "I am in inner function";
console.log(innerVar); // ✅ Accessible (Declared in innerFunction)
console.log(outerVar); // ✅ Accessible (Found in outerFunction)
console.log(globalVar); // ✅ Accessible (Found in global scope)

// Block Scope inside innerFunction


if (true) {
let blockLet = "I am block-scoped (let)";
const blockConst = "I am block-scoped (const)";
var blockVar = "I am function-scoped (var)";

console.log(blockLet); // ✅ Accessible (Inside block)


console.log(blockConst); // ✅ Accessible (Inside block)
console.log(blockVar); // ✅ Accessible (Inside block)
}

// console.log(blockLet); // ❌ ReferenceError (Not accessible


outside block)
// console.log(blockConst); // ❌ ReferenceError (Not accessible
outside block)
console.log(blockVar); // ✅ Accessible (var is function-scoped,
not block-scoped)
}

innerFunction();
}

outerFunction();

console.log(globalVar); // ✅ Accessible (Declared in global scope)


// console.log(outerVar); // ❌ ReferenceError (Not accessible outside
outerFunction)
// console.log(innerVar); // ❌ ReferenceError (Not accessible outside
innerFunction)

© Hornbill Coding Society +91 9662332503 Hornbillcodingsociety.com 59


JavaSCRIPT

In the given code, inner scopes can access variables from their parent scopes, following JavaScript’s lexical
scoping and scope chain rules.

e.g., The innerFunction can access outerVar from outerFunction because outerFunction is its parent scope.

Similarly, innerFunction and outerFunction can both access globalVar since it is declared in the global scope.

This also means that if a variable is not found in the current scope, JavaScript will look up the scope chain to find
it. This process is called variable lookup.

However, this lookup only works upwards, meaning, a parent scope can never access variables from a child
scope.

For instance, outerFunction cannot access innerVar from innerFunction, and the global scope cannot access
either outerVar or innerVar.

let's examine block


scope:

Variables declared with


let and const inside an
if block or for loop are
restricted to that block.

However, var does not


follow block scope and
instead attaches itself
to the nearest function
scope (or the global
scope if no function
exists).

This is why in the code:


blockLet and blockConst inside the if block are not accessible outside the block.

But blockVar, declared with var, is accessible outside because it is function-scoped, not block-scoped.

Note : When a scope requires access to a variable but cannot locate it within its own context, it traverses
the scope chain, searching for the variable in its parent scopes. If the variable exists in an ancestral
(Parent or grandparent) scope, it is utilized accordingly. However, if it remains unresolved throughout
the chain, a ReferenceError is thrown. This mechanism, known as variable lookup ensures that
variables are not duplicated across scopes. Instead of being copied, scopes dynamically reference
variables by ascending the scope chain until the required identifier is found.
extremely important to note is that this does not work the other way around. A certain scope will
never, ever have access to the variables of an inner scope. only parent scope can be used, but no
child scopes and this occours because of the lexical scoping.

60 Java Script +91 9662332503 Hornbillcodingsociety@gmail.com


JavaSCRIPT

If two code block are sibling of each other i.e., they don’t share parent child relation ship then they don’t have
access to each others variables. So we can say scope chain works only upwards and not sideways.

Consider variable as money you can use your grandparents and greatgrandparents money but they can’t use
yours

17.3 SCOPE CHAIN VS CALL STACK

The scope chain is determined by the structural placement of functions within the code, reflecting how
functions are nested rather than the sequence in which they execute. In contrast, the call stack
manages the order of function execution, determining which function is currently running and tracking
execution flow.

It is essential to note that the scope chain and call stack are independent concepts. While the scope chain
retrieves variable environments from execution contexts, it does not influence the order in which
functions are executed. The sequence of function calls in the call stack has no bearing on how variables
are resolved within the scope chain.

17.4 INTERVIEW QUESTIONS

• What is an execution context in JavaScript? (Accenture )


• What are the three main components of an execution context? (Accenture, Wipro, Infosys)
• What is the difference between global scope, local scope block scope ?(Infosys, Accenture, NeosoftTech,
level9Yrips)
• What is scope in JS ?
• Explain the role of the this keyword in the execution context. How does it behave differently in arrow
functions? (IBM, Infosys, Cognizant)
• What is lexical scoping, and how does it influence variable lookup in JavaScript? (Neosoft Tech, Mindtree)
• How does JavaScript resolve variables that are not found in the current execution context?
• What is the difference between the variable declared with let, const and var? (Mindtree, NeosoftTech)
• Describe the concept of variable lookup in JavaScript. How does the scope chain help in resolving variables?
• Is there any relation between call stack and scope chaining ? explain with the functionalities of both!

© Hornbill Coding Society +91 9662332503 Hornbillcodingsociety.com 61


CHAPTER
Veriable Hoisting &
18
Temporal Dead Zone

In the execution context of JavaScript we have Scope Chain, Variable Chapter Outline
environment and this keyword of which scope chain was discussed in the
last chapter and in this chapter we are going to study the variable 18.1 Variable hoisting
environment and this keyword
Hoisting with Var

Hoisting with let and


18.1 VARIABLE HOISTING
const
Hoisting is a JavaScript mechanism where variable and function 18.2 Function hoisting
declarations are moved (hoisted) to the top of their containing scope Function declaration
during compilation. hoisting basically make some types of variables hoisting
accessible, or let’s say This allows variables and functions to be used Function expression

before they are declared hoisting


Arrow function hoisting
Hoisting occurs in two ways:
18.3 Best Practices
1. Variable Hoisting : Moves variable declarations to the top but does 18.4 Temporal dead zone
not initialize them. TDZ with let

2. Function Hoisting : Moves function declarations to the top, including TDZ with const

their definition. TDZ with var


18.5 Interview Questions
Behind the scenes, JavaScript scans the code for variable declarations
before execution. This process occurs during the creation phase of the
execution context. During this phase, each identified variable is
assigned as a property in the variable environment object.

Variables declared using var, let, and const behave differently when
hoisted.

• HOISTING WITH VAR


JavaScript hoists var declarations but does not assign them a value.
The variable is set to undefined until it is initialized.

Actual code Behind the scenes


console.log(a); // Output: var a;
undefined console.log(a); // undefined
var a = 10; a = 10;
console.log(a); // Output: 10 console.log(a); // 10
JavaSCRIPT

• HOISTING WITH LET AND CONST


Unlike var, variables declared with let and const are hoisted but not initialized.
Accessing them before declaration results in a ReferenceError.
This is because let and const are in the temporal dead zone (TDZ) until their declaration is encountered.

Let const
console.log(b); // ReferenceError: Cannot access 'b' console.log(c); // ReferenceError: Cannot access 'c'

before initialization before initialization

var b = 20; var c = 30;

console.log(b); // Output: 20 console.log(c); // Output: 30

Key Differences in Variable Hoisting:

Keyword Hoisted? Default Value Can be Redeclared? Can be Updated?


var Yes Undefined Yes Yes
let Yes No (TDZ Error) No Yes
const Yes No (TDZ Error) No No

18.2 FUNCTION HOISTING

Functions are hoisted differently than variables. There are two types of functions in JavaScript:

1. Function Declarations – Fully hoisted (Can be used before declaration).


2. Function Expressions (including Arrow Functions) – Only the variable is hoisted, not the function definition.

• FUNCTION DECLARATION HOISTING


Function declarations are fully hoisted, meaning both the function name and its definition move to the top.

a number. The data type of NaN is Number

greet(); // Output: Hello, World!

function greet() {

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

Even though greet() is called before its definition, it works because function declarations are fully hoisted.

• FUNCTION EXPRESSION HOISTING

In function expressions, only the variable is hoisted, not the function itself. It depends on using var or

let/Const If declared using Var it’s value is undefined, with let and const it’s not usable before it is declared

in the code because they are hoisted in the temporal dead

© Hornbill Coding Society +91 9662332503 Hornbillcodingsociety.com 63


JavaSCRIPT

Function expression using var Function expression using let or const

console.log(sayHello); // Output: undefined console.log(sayHi); // ReferenceError: Cannot access


var sayHello = function() { 'sayHi' before initialization
console.log("Hello!"); let sayHi = function() {
}; console.log("Hi!");
sayHello(); // Output: Hello! };

Since let and const have a temporal dead zone, accessing sayHi before declaration throws an error,
logic of variable declreation apply on the function name itself in this case.

• ARROW FUNCTION HOISTING

Arrow functions behave like function expressions with var .

Arrow function using var Arrow function using let or const

console.log(sum); // undefined console.log(subtract); // ReferenceError: Cannot


access subtract before initialization
var sum = (a, b) => a + b;
const subtract = (a, b) => a - b;
console.log(sum(2, 3)); // 5

This results in a ReferenceError due to the temporal dead zone

Only the variable sum is hoisted since it is declared with var (with undefined), function definition is not hoisted.

Hoisted Initial values Scope

Function declaration Yes Actual function Block

Var variable Yes Undefined Function

Let and const variable No <Uninitialised>TDZ Block

Function expression and Depends on using var or let/Const


arrow function
If declared using Var it’s value is undefined, with let and const it’s not usable
before it is declared in the code because they are hoisted in the temporal dead
zone

18.3 BEST PRACTICES

• Use let and const instead of var : This prevents unexpected behavior due to undefined values.
• Declare variables at the top of their scope : This improves readability and prevents unexpected hoisting
behavior.
• Use function expressions or arrow functions: when hoisting is not required. It Helps avoid confusion with
function declarations.
• Be cautious when using this in hoisted functions : this behaves differently inside hoisted functions and can
lead to unexpected results.

64 Java Script +91 9662332503 Hornbillcodingsociety@gmail.com


JavaSCRIPT

18.4 TEMPORAL DEAD ZONE

The Temporal Dead Zone (TDZ) is the time between the start of a block’s execution and the point at which a
variable declared with let or const is initialized. During this phase, the variable exists but is inaccessible, and
attempting to access it results in a ReferenceError.

• APPLIES TO LET AND CONST VARIABLES : Unlike var, variables declared with let and const do not get
assigned undefined during hoisting. Instead, they remain uninitialized until their declaration is encountered
in the code.
• EXISTS FROM THE START OF THE SCOPE UNTIL DECLARATION : The TDZ starts when the scope (like a
function or block) is entered and ends when the variable is assigned a value.
• TRYING TO ACCESS A VARIABLE IN TDZ THROWS A Referenceerror

TDZ with let TDZ with const Hoisting with Var

console.log(myVar); // console.log(y); // console.log(x); // Undefined (No


ReferenceError: Cannot access ReferenceError : Cannot access TDZ for var)
'myVar' before initialization 'myVar' before initialization
var x = 5;
let myVar = 10; // const y = 20;
console.log(x); // 5
Initialization, TDZ ends console.log(y); // 20

console.log(myVar); // 10

📔Note : const has a TDZ like let, but it must be initialized at the time of declaration. Since variable declared
with const can’t be reassigned so it must be initialisd at the time of declartation.

The primary reason for introducing the Temporal Dead Zone (TDZ) is to make it easier to identify and prevent
errors. Using a variable before its declaration, when it is still undefined, can lead to serious and difficult-to-debug
issues. The TDZ helps enforce good coding practices by ensuring that variables are accessed only after they have
been properly declared, reducing the likelihood of unexpected behavior in the code.

18.5 INTERVIEW QUESTIONS

• What is Variable hoisting and function hoisting? (Infosys, mindtree, Accenture, cognizant, Delloite, asked in
every interview)
• What’s the difference in hoisting in let, const and var ? (Infosys, Kartine, Accenture, cognizant, Delloite)
• What is difference between function declarartion hoisting and function expression hoisting ?
• What is temporal dead zone ? (Infosys, Kartine, analytics stupa, cognizant, asked in every almost interview)
• How does function declaration hoisting differ from function expression hoisting?

© Hornbill Coding Society +91 9662332503 Hornbillcodingsociety.com 65


CHAPTER

19 This Keyword

In JavaScript, the this keyword is a fundamental component of every Chapter Outline


execution context, created uniquely for each function invocation. It is
one of the three key elements of the execution context, alongside the 19.1 Ways to call function
variable environment and the scope chain.
Function as a method

The this keyword generally refers to the owner of the function in which Normal function
it is used, effectively pointing to the object that invoked the function. Arrow function
However, its value is not static; rather, it is dynamically determined Function call as event
based on how the function is called. The binding of this is established at listner
the time of function execution, making it a crucial concept for What this keyword is not

understanding JavaScript’s behavior in different contexts. 19.2 This keyword in action


this calling two different
There are four different ways in which function can be called and
object
behaviour of this keyword varies according to the nature of function. this in standalone
function
19.1 WAYS TO CALL A FUNCTION
19.3 Interview Questions
1. CALL FUNCTION AS A METHOD

When a function is attached to an object and invoked as a method, the


this keyword within that method refers to the object on which the
method is called. In other words, this points to the object that initiates
the method execution.

Note: A function defined inside an object is called a method of


that object when it is invoked as a property of the object.

const sachin = {
name : 'Sachin Tendulkar',
debutYear : 1989,
retirementYear: 2013,
totalYearsPlayed: function () {
return this.retirementYear - this.debutYear;
}
};
sachin.yearsPlayed ( ); // invoking method on the object
In this example, the totalYearsPlayed function is defined within the
sachin object, making it a method of that object. When invoking the
JavaSCRIPT

method using sachin.yearsPlayed( ), the function is executed in the context of the sachin object. As a result,
the this keyword inside the method refers to the sachin object, allowing it to access its properties. This happens
because the method is being called on the sachin object itself.

2. CALLING FUNCTION AS NORMAL FUNCTION

When a function is not invoked as a method and is not attached to any object, the this keyword inside it will be
undefined in strict mode. However, in non-strict mode(Sloppy mode), this defaults to the global object—which
is the window object in a browser environment. This behavior can lead to unintended side effects, making it
another strong reason to always enable strict mode in JavaScript.

3. ARROW FUNCTION

Unlike regular functions, arrow functions do not have their own this keyword . Instead, when this is used
inside an arrow function, it inherits the this value from its surrounding (or parent) function. This behavior is
known as lexical this, meaning that the this reference is determined by the lexical scope in which the
arrow function is defined, rather than how it is invoked.

4. FUNCTION CALLED AS AN EVENT LISTNER (Callback):

When a function is invoked as an event listener, the this keyword always refers to the DOM element to which
the event handler is attached.

Additionally, functions can be called in various other ways, such as using the new keyword (for object
instantiation) or the call, apply, and bind methods, each of which influences how this is determined.we shall see
it in the following chapters

What This keyword is not

It is also crucial to understand what the this keyword does not refer to. It never points to the function in which
it is used, nor does it refer to the function’s variable environment. Rather it points to the object that call the
the method.

19.2 THIS KEYWORD IN ACTION

As mentioned earlier, the this keyword refers to the object that calls the method, not necessarily the object in
which the method is defined. In the example below, the totalYearsPlayed method is written inside the sachin
object, which might lead us to assume that this automatically refers to sachin. However, this is not the case. The
this keyword points to the sachin object only because it is the object that invokes the method—
sachin.totalYearsPlayed( )

We can conclude that the this keyword always refers to the object that calls the method. This means that if
another object invokes the method, this will no longer refer to the original object but will instead point to the
new calling object. This remains true even if the method is not explicitly defined inside the new object but is
merely a copy of the original method, which still resides within the sachin object. The following example
illustrates this concept.

© Hornbill Coding Society +91 9662332503 Hornbillcodingsociety.com 67


JavaSCRIPT

Let’s create another object:

const christianoRonaldo = {

name: "Christiano Ronaldo",

debutYear: 2003,

retirementYear: 2030

};

Now, we copy the totalYearsPlayed method from sachin and assign it to christianoRonaldo

christianoRonaldo.totalYearsPlayed = sachin.totalYearsPlayed;

When christianoRonaldo object calls the totalYearsPlayed method this in this case will point to
christianoRonaldo object

christianoRonaldo.totalYearsPlayed();

// Output: { name: 'Christiano Ronaldo', debutYear: 2003, retirementYear: 2030 }

// 27

The this keyword always refers to the object that invokes the method. As a result, if a different object calls the
same method, this dynamically adjusts to that object, even if the method was originally defined elsewhere and
only referenced from the original object.

In this example, this now refers to christianoRonaldo because it is the object executing the method. Although
the method was initially defined within the sachin object, this dynamically binds to the calling object,
highlighting its flexible nature—it is not tied to a specific object but is determined at runtime based on the
invocation context.

This keyword in the standalone function

Since functions and methods are just values, we can extract a method and store it in a separate variable without
immediately invoking it. Let’s create a standalone function:

Since the function is now called in the global context (not as a method of any object), this is undefined in strict
mode, or it defaults to the global window object in browser environment in non-strict mode. This further
highlights that this depends entirely on how a function is const separateFun = sachin.totalYearsPlayed;
invoked rather than where it was originally defined.
separateFun(); // Output: undefined
now if we make christianoRonaldo object call the
totalYearsPlayed method then this keyword will point to the ChristianoRonaldo object

christianoRonaldo.totalYearsPlayed( ) // output : { name: 'Christiano Ronaldo', debutYear: 2003, retirementYear: 2030,


totalYearsPlayed: [Function: totalYearsPlayed] } 27

68 Java Script +91 9662332503 Hornbillcodingsociety@gmail.com


JavaSCRIPT

Here, we can observe that the this keyword refers to the object that invokes the method—in this case,
christianoRonaldo calling totalYearsPlayed() Output : {name : 'Christiano ….} 27

Although the method was originally defined inside the sachin object, this still points to christianoRonaldo because
it is the object making the method call. This demonstrates that the this keyword is highly dynamic rather than
static—it is determined by how a function is called, not where it was originally defined.

Normal function Arrow function This keyword in method

console.log(this) totalYearPlayed = (debuteYear, const sachin = {


retirementAge) =>{ name : 'Sachin Tendulkar',
const totalYearPlayed =
function(debuteYear, console.log(retirementYear – debutYear : 1989,
retirementAge){ debuteYear) retirementYear : 2013,
console.log(retirementYear – console.log(this) totalYearsPlayed : function ( ) {
debuteYear)
} console.log (this )
console.log(this) return this.retirementYear -
totalYearPlayed(2013, 1989)
this.debutYear;
}
}
totalYearPlayed(2013, 1989)
};
sachin.yearsPlayed ();

Output: window{parent : window …..} Output : 24 Output : sachin {name : Sachin ….}

24 Window {} 24

Undefined Note: Arrow function dosen’t get


it’s this keyword rather it uses lexical
this keyword i.e., this keyword of the
parent function

19.3 INTERVIEW QUESTIONS

• What is the this keyword in JavaScript? (asked in almost all intermediate and advanced level interviews e.g.,
Infosys, TCS, Accenture, )
• Explain This keywords role in function execution contexts!
• How is the value of this determined in different function invocation contexts? (Infosys, TCS, Wipro,
Accenture, almost asked in every interview)
• What is the difference between this in regular functions and arrow functions?
• Explain lexical this and how it works in arrow functions.
• What is the this keyword in the global context? (One of the most common question)

© Hornbill Coding Society +91 9662332503 Hornbillcodingsociety.com 69


CHAPTER
Regular vs Arrow
20
function

we already know that arrow function don’t get it’s own this keyword. Chapter Outline
There is stark difference in the behaviour of the this keyword in arrow
function and regular function expression 20.1 Regular function vs.
Arrow function
20.1 REGULAR FUNCTION VS. ARROW FUNCTION
20.2 Interview Questions

const restaurant = {

name: 'The Gourmet Spot',

established: 2010,

getAge: function () {

console.log(this);

console.log(2037 - this.established);

},

greet: () => console.log(`Welcome to ${this.name}`)

};

restaurant.greet(); // Welcome to undefined

console.log(this.name); // undefined

An object literal may appear to create a new scope, but it does not.
Instead, it simply defines an object, and everything inside it remains in
the surrounding scope. it means that methods within the object,
including arrow functions, do not create their own scope.

Since arrow functions do not have their own this keyword, they inherit
this from the surrounding scope, which, in this case, is the global scope.
If we attempt to access a property such as this.name inside an arrow
function within an object literal, it will refer to name on the global object
(e.g., window in browsers). If name is not defined on the global object,
the result will be undefined instead of an error. window is this
keyword inside of this arrow function, even though that arrow
function was called by the restaurant object.
JavaSCRIPT

This behavior can be particularly risky when using var to declare variables, as var creates properties on the
global object in non-strict mode, potentially leading to unexpected results. that's yet another reason not to
use var.

As a best programming practice it is recommended to not use arrow function as method in any object.

const restaurant = {

name: 'The Gourmet Spot',

established: 2010,

getAge: function ( ) {

console.log(this);

console.log(2025 - this.established);

const isOlderThanDecade = function ( ){

console.log(`restaurant is ${2025 - this.established} years old` )

isOlderThanDecade ( ) //normal function call so this → undefined

},

greet: ( ) => console.log(`Welcome to ${this.name}`)

};

restaurant.greet( ); // Welcome to undefined

console.log(this.name); // undefined

A common mistake occurs when a regular function is defined inside a method and attempts to use the this
keyword. In the getAge method of the restaurant object, we define the isOlderThanDecade function inside it.
Even though it is inside a method, isOlderThanDecade is still a regular function call, meaning it does not inherit
this from getAge.

As a result, when this.established is accessed inside isOlderThanDecade, it refers to undefined, leading to an


error: "Cannot read property 'established' of undefined."

This happens because the nested function behaves as if it were defined outside the method, where this is either
undefined (in strict mode) or refers to the global object (window in browsers, or {} in Node.js)

How to use this keyword inside a regular function call inside method

1. One way to use the this keyword inside a function within an object is by assigning it to an external variable,
commonly named self. Before calling the function, self is set to this, and within the function body, self is
used instead of this. This approach is considered an older solution.
2. Another solution is to use an arrow function inside a method when a function is required within it. This
works because arrow functions do not have their own this keyword. Instead, they inherit this from their

© Hornbill Coding Society +91 9662332503 Hornbillcodingsociety.com 71


JavaSCRIPT

parent scope, which in this case is the getAge( ) method. Essentially, an arrow function retains the this
value of its enclosing context.

20.2 ARGUMENTS KEYWORDS

In addition to the this keyword, functions can also access the arguments keyword. However, like
this, the arguments keyword is only available in regular functions (i.e., function expression and
function decleration but not in arrow function). In modern JavaScript, its importance has decreased,
as there are more efficient methods for handling multiple parameters.

Const multiply = function( a, b){

Console.log(a*b);

return a*b;

};

multiply( 6, 2 ); // Arguments(2) [5, 2, callee: ƒ, Symbol(Symbol.iterator): ƒ]

// 12

// We can add even more arguments and those will appear in the arguments
keywords

// In case of arrow function → Uncaught ReferenceError: arguments is not


defined

20.3 INTERVIEW QUESTIONS

• What are the key differences between regular functions and arrow functions in terms of the this keyword in
JavaScript? (Infosys, TCS)
• Why do arrow functions inherit this from their parent scope, and how does this behavior affect their use
inside methods of an object?

72 Java Script +91 9662332503 Hornbillcodingsociety@gmail.com


CHAPTER
Memory Management
21
In Java Script

Memory management in JavaScript refers to the process by which the Chapter Outline
JavaScript engine allocates memory for variables and later releases it
when those variables are no longer needed. Effective memory 21.1 Memory management
management ensures that applications run smoothly and efficiently Memory management in
without unnecessary memory consumption. details
Copy reference and
In this chapter, we will explore how JavaScript handles memory
object
allocation, where variables are stored, and how memory is freed up
Anamoly of const
when it is no longer in use. Essentially, we aim to answer the changing in reference
fundamental question: How and where are variables created in type
JavaScript? Copy of primitive data
21.2 Shallow copy vs. Deep
21.1 MEMORY MANAGEMENT copy
Unlike lower-level programming languages such as C or C++, where Shallow copy

developers must manually allocate and manage memory for variables, Deep copy / Deep clone
21.3 Life cycle of value in
JavaScript handles memory management automatically. This simplifies
memory
the coding process, enhances development speed, and minimizes the
21.4 Automatic garbage
risk of issues like memory leaks.
collection
Every value created in a JavaScript application follows a process known
Memory leakage
as the memory lifecycle. This lifecycle begins with memory allocation 21.5 Interview Question
whenever a new value is created. For instance, when assigning a value
to a variable, the JavaScript engine automatically reserves a portion of
memory to store that value—whether it’s a simple number like 25.7, an
object, or even a function.

As the application runs in the user’s browser, this allocated memory is


utilized whenever the stored value is accessed, whether for reading,
writing, or updating. Eventually, when the value is no longer needed, it
reaches the final stage of the lifecycle—memory release. At this point,
the value is removed from memory, freeing up space for new values
in the future.

• MEMORY MANAGEMENT IN DETAILS


Different types of values are stored in different locations within the
JavaScript engine.
JavaSCRIPT

JavaScript values fall into two categories: primitive values and objects. Primitive data types include numbers,
strings, Booleans, undefined, null, symbols, and BigInts. Everything else—such as objects created with object
literals, arrays, and even functions—falls under the category of objects.

The JS engine consists of two primary components:

1. The Call Stack, where functions are executed.

2. The Memory Heap, where objects are stored.

All objects are allocated memory within the heap, while primitive values are typically stored in the call stack,
specifically within the execution context in which they are created.

Note : JS engines are highly optimized and may make some exceptions. e.g., a very long string—despite
being a primitive—might be stored in the heap instead of the call stack to optimize performance.

In addition to primitives and objects, JavaScript also utilizes references to objects, which are stored in the call
stack.

Since objects themselves are stored in the heap, there needs to be a way to access them throughout the code.
This is where references come into play. Instead of storing the actual object in the call stack, JavaScript stores
a reference, which acts like an address pointing to the object's location in the heap. This allows the object to be
accessed and manipulated without duplicating its data in memory.

In the execution context, the variable will store a reference to the object rather than the object itself. This means
that instead of holding the actual object, the variable contains a memory address that points to the object's
location in the heap. Essentially, the variable acts as a reference that allows access to the object stored in
memory heap.

Java Script Engine


Objects Primitive Data type

1. Object 1. Number
2. Array Heap/Unstructured 2. String
Call Stack/Code
3. Date time memory pool 3. Boolean
execution
4. Functions 4. Undefined
5. JSON 5. Null
6. SET 6. symbols
7. MAP 7. Bigint

Objects that our web


application needs

• COPY REFERENCE AND OBJECT


Let’s see how to copy the refrence types such as object, array , set , map etc. and implication of copying them

74 Java Script +91 9662332503 Hornbillcodingsociety@gmail.com


JavaSCRIPT

const employee = 'Michael';

const experience = calculateExperience(2015);

let updatedExperience = experience;

updatedExperience += 2;

const company = {

name: 'TechCorp',

location: 'San Francisco',

};

// making shallow copy

const branchOffice = company;

branchOffice.location = 'Seattle';

console.log(company);

function calculateExperience(joiningYear) {

const currentYear = 2025;

return currentYear - joiningYear;

If we create a copy of the company object and assign it to a new variable called branchOffice, an interesting
concept comes into play. Since a variable like company stores only a reference to the object in memory, copying
the variable doesn’t create a new object. Instead, it simply copies the reference. In other words, when we assign
branchOffice = company, we are not duplicating the object itself but rather copying the reference stored in
the call stack (let’s say memory address).

As a result, both branchOffice and company point to the exact same object in the heap. This means that if we
modify any property of branchOffice, such as updating the location from 'San Francisco' to 'Seattle', the change
will also be reflected in company—and vice versa. This demonstrates that both the original object and its "copy"
in the call stack share the same reference to a single object in the heap.

Call Stack Heap

Identifier Address(fictional) Value

employee 001 Michael'

Experience 002 10 Address Value

updatedExperience 003 10 F25UZ const company = {

updatedExperience - 12 name: 'TechCorp',

company 004 F25UZ location: 'San Francisco',

branchOffice };

© Hornbill Coding Society +91 9662332503 Hornbillcodingsociety.com 75


JavaSCRIPT

Note : Functions, behind the scenes, are also objects. This means that they are stored in the heap, while
the variable with the same name holds a reference to the function object in memory.

• ANAMOLY OF CONST CHANGING IN REFERENCE TYPE


But variable
In the given code, the company and branchOffice objects are declared with
const can’t be
declared using const, meaning their reference in memory
reassigned
remains unchanged. However, we were still able to modify
the location property of branchOffice, which also affected
company. This happens because both variables reference the
same object in the heap, and modifying a property does not
change the reference itself.

What we cannot do is assign company to an entirely new


object, such as company = { name: 'InnovateTech', location:
'New York' }, because this would require changing the reference stored in the company constant. Since
const prevents reassigning a new reference, attempting this operation would result in an error. However,
if company were declared with let, reassignment to a new object would be possible.

• COPY PRIMITIVE DATA TYPE : In primitive values, each variable stores its own independent copy of the
value, with no references involved so any copy of primitive type is always created at new memory location.

21.2 SHALLOW COPY VS DEEP COPY

A shallow copy creates a new object but only copies references for nested objects. This means that if the
original object contains another object inside it, both the original and copied objects will still point to the same
inner object in memory. Modifying the nested object in one will also affect the other.

const company = {

name: 'TechCorp',

location: 'San Francisco',

employee : [ “Vladimir”, “Evan”, “Dimitri”]

};

//shallow copy

const branchOffice = company;

branchOffice.employee.push(‘Surgey’);

console.log(company); // employee : [ “Vladimir”, “Evan”, “Dimitri”, “Surgey“] → change in the original object

• DEEP COPY/ DEEP CLONE : A deep copy, on the other hand, creates an entirely new object, including copies
of all nested objects. This ensures that changes in the copied object do not affect the original.

76 Java Script +91 9662332503 Hornbillcodingsociety@gmail.com


JavaSCRIPT

const deepCopy = JSON.parse(JSON.stringify(company)); // Deep copy

deepCopy.employee.push(‘vadim’);

console.log(deepCopy.employee); // Output: [ “Vladimir”, “Evan”, “Dimitri”,’Vadim’]

console.log(company.employee); // Output: [ “Vladimir”, “Evan”, “Dimitri”]

OR we have another method

Variable COPY = structuredClone(object to be copied )

cosnt deepCopy2 = structuredClone(company)

deepCopy2.employee.push(‘Boris’);

console.log(deepCopy2.employee); // Output: [ “Vladimir”, “Evan”, “Dimitri”, ‘Boris’]

console.log(company.employee); // Output: [ “Vladimir”, “Evan”, “Dimitri”]

21.3 LIFE CYCLE OF VALUE IN MEMORY

In JavaScript, every value follows a memory lifecycle: allocation, usage, and deallocation.

1. Memory Allocation – When a value is created, memory is allocated for it.


2. Usage – The allocated memory is used while the value is needed in the program.
3. Memory Deallocation – Once a value is no longer needed, its memory is freed.

In the call stack, memory management is straightforward. Primitive values are stored in variable
environments, which are automatically removed when the corresponding execution context is popped off the
stack. This ensures efficient memory cleanup.

In the global execution context, variables persist indefinitely because this context never disappears, meaning
their values remain in memory.

Memory management becomes more complex when dealing with the heap. To remove unused objects and free
up memory, JavaScript engines utilize a process called garbage collection. This is a core mechanism for memory
management in any JavaScript engine.

It’s important to note that garbage collection is handled entirely by the JavaScript engine, which runs it
automatically whenever necessary. Developers cannot manually trigger or control when memory is cleared, but
this is actually beneficial. Automatic memory management simplifies development and ensures efficient
resource handling.

Ways to Implement the garbage collection: there are different ways to implement garbage collection, but all
modern engines use an algorithm called mark-and-sweep.

The mark-and-sweep algorithm for garbage collection begins with the mark phase, where all objects that can be
reached from a root are marked as active. Roots serve as the starting points for identifying accessible objects.
The most common roots include the global execution context, which is always present, and any active execution
contexts of running functions. Beyond the global execution context and function execution contexts, objects can also
be accessed through event listeners, active timers, and closures. These too serve as roots for the mark-and-sweep
algorithm.

© Hornbill Coding Society +91 9662332503 Hornbillcodingsociety.com 77


JavaSCRIPT

In the sweep phase, any objects that were not marked in the first step—meaning they are no longer reachable—
are deleted. This phase allows the system to reclaim the memory occupied by these objects, making it available
for future allocations.

21.4 AUTOMATIC GARBAGE COLLECTION

JavaScript’s automatic garbage collection ensures that memory remains optimized by removing objects that are
no longer accessible. However, garbage collection cannot be manually controlled or triggered through code.
Additionally, the exact timing and frequency of garbage collection depend on several factors, including the
memory usage of the application, available system memory, and the JavaScript engine used by the browser.

One important aspect of memory management is that objects in the global execution context persist
indefinitely. Since the global execution context never disappears, any object defined globally will never be
garbage collected, even if it is no longer needed in the code. and this leads to phenomenon called memory leaks.

• Memory Leaks and Their Causes : A memory leak occurs when an object that is no longer required remains
accessible through a reference from one of the roots, preventing it from being marked for deletion by the
garbage collector. This means the object is retained in memory unnecessarily, leading to inefficient memory
usage.
One common cause of memory leaks is unnecessary references from event listeners and timers. e.g.,
if a timer creates an object and continues to run without being cleared, it keeps referencing the object,
preventing it from being garbage collected. Similarly, event listeners that are no longer needed but remain
active can also hold references to objects, causing memory leaks.

Preventing Memory Leaks : To avoid memory leaks

o Always deactivate timers and event listeners when they are no longer needed, especially if they
reference large objects.

o Avoid defining large objects in the global scope, as they will never be garbage collected.

o Regularly review and optimize memory usage to ensure efficient performance.

By following these practices, developers can effectively manage memory usage and prevent unnecessary
memory retention in JavaScript applications

21.5 INTERVIEW QUESTIONS

• How does JavaScript handle memory allocation and deallocation? (Wipro)


• How does JavaScript store primitive values and objects in memory? (almost asked in every experienced level
3 interview)
• What is the difference between a shallow copy and a deep copy of an object? (asked in almost all interview)
• What is a memory leak, and how does it occur in JavaScript?
• How would you create a deep copy of the following object? (Accenture, Kartine)

78 Java Script +91 9662332503 Hornbillcodingsociety@gmail.com


CHAPTER
Data Structure &
22
Destructuring

We are going to see some modern Java Script data Structure and Modern Chapter Outline
ES 6+ operators such as destructuring in array and object.

22.1 Array destructuring


22.1 ARRAY DESTRUCTURING
Basic syntax
Destructuring is an ES6 feature that simplifies the process of extracting Skipping elements
or unpacking values from arrays or objects and storing them in separate Assigning default values

variables. It allows developers to break down complex data structures Swapping of variables

into smaller, more manageable parts like variable. Destructuring from


function that return
For arrays, destructuring provides a concise way to extract elements and value
assign them to variables efficiently. This eliminates the need for Nested array destructure
repetitive indexing and enhances code readability. Swapping array elements
in loop
• BASIC SYNTAX OF ARRAY DESTRUCTURING
Using rest operatoer in

const numbers = [10, 20, 30]; destructuring

// Destructuring assignment 22.2 Object destructuring


Basic syntax
const [first, second, third] = numbers;
Setting different variable
console.log(first); // Output: 10
name
console.log(second); // Output: 20
Nested objet
console.log(third); // Output: 30 destructuring
Default value in object
Although it may look like an array, it's actually a destructuring
destructuring
assignment. Whenever JavaScript encounters this syntax on the left side
Destructuring with
of the equal sign, it recognizes it as destructuring. The original array
function parameter
remains unchanged since we are merely unpacking its values into Rest operator with object
separate variables. destructuring
Spread operator and
• SKIPPING ELEMENTS WHILE DESTRUCTURING : skip elements in an
object destructuring
array by leaving empty spaces between commas.
22.3 Interview Questions
const colors = ["red", "green", "blue", "yellow"];
// Skipping the second element
const [firstColor , , thirdColor] = colors;
console.log(firstColor); // Output: "red"
console.log(thirdColor); // Output: "blue" green is skipped by empty
slot
JavaSCRIPT

• ASSIGNING DEFAULT VALUES : If the array does not contain enough elements (shorter than expected), assign
default values to avoid undefined other wise it will return undefined.
const fruits = ["Apple"];
// Assigning default values
const [fruit1, fruit2 = "Banana"] = fruits;

console.log(fruit1); // Output: "Apple"


console.log(fruit2); // Output: "Banana" (default value)

Since the fruits array contains only one element, fruit2 is assigned "Banana" as the default value.

• SWAPPING VALUES OF VARIABLE : Destructuring provides an easy way to swap variables without using a
temporary variable.

let a = 5, b = 10;
// Swapping values
[a, b] = [b, a];

console.log(a); // Output: 10
console.log(b); // Output: 5

• DESTRUCTURING FROM A FUNCTION RETURN VALUE : Functions that return arrays can be easily
destructured.

function getScores() {
return [85, 90, 95];
}
// Destructuring the return values
const [math, science, english] = getScores();

console.log(math); // Output: 85
console.log(science); // Output: 90
console.log(english); // Output: 95

• NESTED ARRAY DESTRUCTURING : You can destructure values from nested arrays.

const nestedArray = [1, [2, 3], 4];

// Extracting nested values


const [first, [second, third], fourth] = nestedArray;
console.log(first); // Output: 1
console.log(second); // Output: 2
console.log(third); // Output: 3
console.log(fourth); // Output: 4

80 Java Script +91 9662332503 Hornbillcodingsociety@gmail.com


JavaSCRIPT

• PRACTICAL USE CASE: SWAPPING ARRAY ELEMENTS IN A LOOP : useful when iterating over array.

const users = [
["Harry", 25],
["Ronal", 30],
["Hermione", 28]
];

// Looping with destructuring


for (const [name, age] of users) {
console.log(`${name} is ${age} years old.`);
}
// Output
Harry is 25 years old.
Ronal is 30 years old.
Hermione is 28 years old.

• USING THE REST OPERATOR (...) IN DESTRUCTURING : The rest operator (...) allows you to collect remaining
elements into an array.
const numbers = [1, 2, 3, 4, 5];
// Using the rest operator
const [first, second, ...rest] = numbers;
console.log(first); // Output: 1
console.log(second); // Output: 2
console.log(rest); // Output: [3, 4, 5] (remaining elements)

...rest collects all remaining values after the first two elements into an array.

22.2 DESTRUCTURING OBJECTS

ES6 (ECMAScript 2015) feature, provides a convenient way to extract properties from an object and assign them
to variables. This technique simplifies code readability and reduces redundancy when working with objects.
Instead of accessing properties using dot notation (object.property), destructuring allows for a more compact
syntax.
• BASIC SYNTAX OF OBJECT DESTRUCTURING

const person = {
firstName: "John",
lastName: "Doe",
age: 30,
};
const { firstName, lastName, age } = person;
console.log(firstName); // Output: John
console.log(lastName); // Output: Doe
console.log(age); // Output: 30

© Hornbill Coding Society +91 9662332503 Hornbillcodingsociety.com 81


JavaSCRIPT

Here, the properties firstName, lastName, and age are extracted from the person object and assigned to
corresponding variables with the same names.

• DIFFERENT VARIABLE NAMES : store the properties in variables with names different from the object’s
property names, we can achieve it using a colon (:)

const employee = {
name: "Alice",
position: "Developer",
salary: 50000,
};
const { name: empName, position: jobTitle, salary: annualIncome } =
employee;
console.log(empName); // Output: Alice
console.log(jobTitle); // Output: Developer
console.log(annualIncome); // Output: 50000

• NESTED OBJECT DESTRUCTURING : If an object contains nested objects, we can destructure them as well.

const student = {
name: "David",
info: {
age: 20,
grade: "A",
address: {
city: "New York",
country: "USA",
},
},
};

const {
name,
info: {
age,
grade,
address: { city, country },
},
} = student;

console.log(name); // Output: David


console.log(age); // Output: 20
console.log(grade); // Output: A
console.log(city); // Output: New York
console.log(country); // Output: USA

82 Java Script +91 9662332503 Hornbillcodingsociety@gmail.com


JavaSCRIPT

• DEFAULT VALUES IN DESTRUCTURING OBJECT : If a property does not exist in the object, JavaScript assigns
undefined. However, we can set a default value to avoid undefined values.

const user = {
username: "coder123",
email: "coder@example.com",
};
const { username, email, role = "User" } = user;
console.log(username); // Output: coder123
console.log(email); // Output: coder@example.com
console.log(role); // Output: User (default value)

Here, role does not exist in the user object, so it takes the default value "User".

• DESTRUCTURING WITH FUNCTION PARAMETERS: destructuring can be used in function parameters to


extract specific values from an object passed as an argument.

function displayUser({ name, age }) {


console.log(`User: ${name}, Age: ${age}`);
}

const userDetails = {
name: "Sophia",
age: 25,
country: "Canada",
};

displayUser(userDetails);
// Output: User: Sophia, Age: 25

Here, the function displayUser directly extracts name and age from the userDetails object.

• REST OPERATOR WITH OBJECT DESTRUCTURING: The rest operator (...) can be used to collect remaining
properties into a separate object.

const product = {
id: 101,
name: "Laptop",
price: 1200,
brand: "TechBrand",
};

const { id, name, ...details } = product;


console.log(id); // Output: 101
console.log(name); // Output: Laptop
console.log(details); // Output: { price: 1200, brand: 'TechBrand' }

© Hornbill Coding Society +91 9662332503 Hornbillcodingsociety.com 83


JavaSCRIPT

• COMBINING OBJECT DESTRUCTURING WITH SPREAD OPERATOR : Destructuring can be used along with the
spread operator to create a copy of an object while modifying specific properties.

const employee = {
name: "Ethan",
department: "IT",
experience: 5,
};

const updatedEmployee = { ...employee, experience: 6, location: "New


York" };

console.log(updatedEmployee);
/* Output:
{
name: "Ethan",
department: "IT",
experience: 6,
location: "New York"
}
*/

Here, the original employee object is copied, experience is updated to 6, and a new property location is added.

22.3 INTERVIEW QUESTIONS

• What is destructuring in array, what can you achieve with the array destructuring ?
• What is object destructuring , what can you achieve with the object destructuring ?
• What is array destructuring in JavaScript? Explain its benefits. (Infosys)
• What happens if an array has fewer elements than the variables defined in destructuring? How can you
handle this issue?

84 Java Script +91 9662332503 Hornbillcodingsociety@gmail.com


CHAPTER
Spread Operator &
23
Rest Operator
We can use spread operator is an ES6 (ECMAScript 2015) feature that Chapter Outline
allows iterable elements (arrays,strings or objects (from ES 2018 even
though objects are not iterable)) to be expanded into individual 23.1 Spread operator- Array
elements. Extracting element from
Array
23.1 SPREAD OPERATOR WITH ARRAY Copying Array

Syntax Merging Multiple Array

const newArray = [...existingArray]; // Expanding an array Adding element While


Copying
const newObject = { ...existingObject }; // Expanding an object
23.2 Spread operator with
• EXTRACTING ELEMENTS OUT OF ARRAY string
const originalArray = [1, 2, 3]; 23.3 Spread operator with
console.log(originalArray); // Output: 1, 2, 3 object
23.4 Spread operator with
• COPYING AN ARRAY
function
const originalArray = [1, 2, 3]; Spread in function call
const copiedArray = [...originalArray]; Spread with math
console.log(copiedArray); // Output: [1, 2, 3] function
Spread with nested data
• MERGING MULTIPLE ARRAYS : The spread operator is useful for
23.5 Rest Parameter
merging arrays instead of using concat().
Rest parameter in array
const array1 = [1, 2, 3]; destructuring.
const array2 = [4, 5, 6]; Rest in function
const mergedArray = [...array1, ...array2]; parameter
console.log(mergedArray); // Output: [1, 2, 3, 4, 5, 6] Spread with rest
Rest in object
• ADDING ELEMENTS WHILE COPYING : insert additional elements
destructuring
while copying an array. removing obj property

const numbers = [2, 3, 4]; 23.6 Spread rest difference


23.7 Interview Questions
const newNumbers = [1, ...numbers, 5];

Note:
❖ The spread operator is similar to destructuring because both help extract elements from an array or
object.

❖ The spread operator (...) can only be used on iterables (like arrays, strings, sets, and objects).
JavaSCRIPT

❖ Key Difference:
o Spread Operator (...) expands all elements from an iterable without creating new variables.
o Destructuring ( [] or {} ) extracts specific elements and assigns them to variables.
❖ Use Case:
o The spread operator is used where values are expected to be separated by commas (e.g., function
arguments, array literals, or object literals). Works on the right side of assignment operator
o Destructuring is used when we need to store extracted elements in variables for later use. Works
on the left side of assignment operator

23.2 SPREAD OPERATOR WITH STRING

Since the spread operator can be used on iterables, it can be applied to strings as well. This allows the spread
operator to convert a string into an array of its individual characters effortlessly.

const str = "Hello";

const charArray = [...str];

console.log(charArray); // Output: ['H', 'e', 'l', 'l', 'o']

23.3 OPERATOR WITH OBJECTS

• COPYING AN OBJECT : It creates a shallow copy of an object, meaning that nested objects are copied by
reference rather than being fully duplicated.
const person = { name: "John", age: 25 };
const copiedPerson = { ...person };

console.log(copiedPerson); // Output: { name: 'John', age: 25 }

• MERGING MULTIPLE OBJECTS : spread operator also be used to merge two or more objects.

const person = { name: "Ram", age: 28 };


const job = { role: "Developer", company: "TechCorp" };

const mergedObject = { ...person, ...job };


console.log(mergedObject); // Output: { name: 'Ram', age: 28, role: 'Developer', company: 'TechCorp' }
• ADDING OR OVERRIDING PROPERTIES : When copying an object, new properties can be added, or existing
ones can be overridden.

const user = { name: "Emma", age: 30 };


const updatedUser = { ...user, age: 31, city: "New York" };

console.log(updatedUser); // Output: { name: 'Emma', age: 31, city: 'New York' }

23.4 SPREAD OPERATOR IN FUNCTION

• USING SPREAD IN FUNCTION CALLS: It can also be used to merge two or more objects.

86 Java Script +91 9662332503 Hornbillcodingsociety@gmail.com


JavaSCRIPT

function sum(a, b, c) {

return a + b + c;

const numbers = [10, 20, 30];

console.log(sum(...numbers)); // Output: 60

Instead of manually passing numbers[0], numbers[1], numbers[2], the spread operator expands the array
elements.

• USING SPREAD WITH MATH FUNCTIONS

const numbers = [12, 45, 78, 23, 56];

console.log(Math.max(...numbers)); // Output: 78

console.log(Math.min(...numbers)); // Output: 12

• SPREAD OPERATOR WITH NESTED DATA STRUCTURES


Since the spread operator creates shallow copies, nested objects or arrays remain referenced
rather than being deeply copied. As a result, any modifications to the nested structure affect both
the original and copied objects.

const person = {
name: "Alice",
details: { age: 30, city: "New York" }
};

const copiedPerson = { ...person };

copiedPerson.details.age = 31;
copiedPerson.name = “Mathew”;

console.log(person.details.age); // Output: 31 (Both object are affected as shallow copy)


console.log(copiedPerson.name); // Output: Mathew (affected as name is the first level property)
console.log(person.name); // Output: Alice (not affected as only first level properties are copied )

23.5 REST PARAMETER AND REST PATTERN

The rest parameter looks identical to the spread operator (...rest) but functions in the opposite way.

• The spread operator is used to expand an array into individual elements. It helps build new arrays or pass
multiple values into a function.

• The rest parameter, on the other hand, collects multiple elements and condenses them into an array.

© Hornbill Coding Society +91 9662332503 Hornbillcodingsociety.com 87


JavaSCRIPT

In simple terms, the spread operator unpacks an array, while the rest parameter packs elements into an array.
With the rest parameter, we can pass any number of arguments into a function, making it highly flexible.

• REST PARAMETER IN ARRAY DESTRUCTURING : In array destructuring, the rest operator can be used
to extract remaining elements into an array.

const fruits = ["Apple", "Banana", "Mango", "Orange", "Grapes"];

const [favorite, secondFavorite, ...otherFruits] = fruits;

console.log(favorite); // Output: Apple

console.log(secondFavorite); // Output: Banana

console.log(otherFruits); // Output: ["Mango", "Orange", "Grapes"]

Note: Since the rest parameter collects all remaining elements and packs them into a new data
structure like an array, it must always appear at the end in a destructuring assignment.
Additionally, there can be only one rest parameter in any destructuring assignment.

• REST OPERATOR IN FUNCTION PARAMETERS : When defining a function, the rest operator enables us
to handle an indefinite number of arguments by collecting them into an array.

function sum(...numbers) {
let total = 0;
for (let num of numbers) {
total += num;
}
return total;
}

console.log(sum(1, 2, 3, 4, 5)); // Output: 15

console.log(sum(10, 20, 30, 40)); // Output: 100

console.log(sum(5, 15)); // Output: 20

• SPREAD OPERATOR WITH REST PARAMETER : In array destructuring, the rest operator can be used to
extract remaining elements into an array.

const consumable = ["Butter", "Oil", "Sugar"];

const fruits = ["Apple", "Banana", "Mango", "Orange", "Grapes"];

const groceryItems = ["Turmeric", "Cardamom", ...consumable, ...fruits];

const [firstItem, secondItem, ...groceryList] = groceryItems;

88 Java Script +91 9662332503 Hornbillcodingsociety@gmail.com


JavaSCRIPT

console.log(firstItem); // Output: Turmeric

console.log(secondItem); // Output: Cardamom

console.log(groceryList); // Output: ["Butter", "Oil", "Sugar", "Apple", "Banana", "Mango", "Orange", "Grapes"]

• REST OPERATOR IN OBJECT DESTRUCTURING: In object destructuring, the rest operator collects
remaining properties into a new object. This is particularly useful when excluding certain
properties while keeping the rest.

const car = {

brand: "Toyota",

model: "Camry",

year: 2022,

color: "Blue"

};

// Extracting brand and model, and grouping the rest

const { brand, model, ...specs } = car;

console.log(brand); // Output: Toyota

console.log(model); // Output: Camry

console.log(specs); // Output: { year: 2022, color: "Blue" }

• PRACTICAL USE CASE: REMOVING A PROPERTY FROM AN OBJECT : In object destructuring, the rest
operator collects remaining properties into a new object. This is particularly useful when excluding
certain properties while keeping the rest.

const user = {

id: 1,

username: "techguru",

password: "secure123"

};

// Removing the password

const { password, ...publicData } = user;

console.log(publicData);

// Output: { id: 1, username: "techguru" }

This is useful for handling sensitive data like removing passwords before sending an object over the network.

© Hornbill Coding Society +91 9662332503 Hornbillcodingsociety.com 89


JavaSCRIPT

23.6 DIFFERENCE BETWEEN SPREAD AND REST OPERATOR

Both the spread (...) and rest (...) operators share the same syntax, but they serve opposite purposes depending
on where they are used.
• The spread operator is used in places where values are expected to be separated by commas. It is commonly
used to expand arrays or objects. Works on the right side of assignment operator
• The rest operator, on the other hand, is used where we would typically write variable names separated
by commas. It is used to collect multiple values into an array or object. Works on the left side of assignment
operator

In simple terms:
Use spread (...) when expanding values.

Use rest (...) when gathering values into a variable.

23.7 INTERVIEW QUESTIONS

• What is the key difference between the spread operator and the rest parameter in JavaScript? (Infosys, TCS,
Wipro, Accenture, persistant systems almost asked in every interview)
• How can you use the spread operator to merge two objects while adding a new property? (Delloite, Atos,
Accenture)
• Write a JavaScript function that accepts any number of arguments and returns their sum using the rest
parameter. (Infosys, TCS, mindtree)
• Explain how the spread operator works with objects. What are its limitations? (Capgemini)
• How do you swap value of two variable value without using third variable (Capgemini, Mindtree, Infosys,
Most common question)

90 Java Script +91 9662332503 Hornbillcodingsociety@gmail.com


\

CHAPTER
Short-circuiting,
24 Nullish coalescing,
Logical Assignment
Logical operators (||, &&, ??) in JavaScript enable short-circuiting, Chapter Outline
returning values efficiently without evaluating unnecessary expressions.
Modern enhancements like logical assignment operators (||=, &&=, ??=) 24.1 short-circuiting
optimize code, improving readability and performance while handling
short-circuiting with OR
default values and conditional logic effectively.
short-circuiting with AND

24.1 SHORT-CIRCUITING Invalid conversion

24.2 Nullish Coalescing


So far, we have observed that the result of operations involving logical
24.3 Logical assignment
operators is always a Boolean value, but that is not necessarily the case.
operator
Some properties about logical operators Logical assignment with
OR (||=)
➢ They can use any data type (String, Boolean, number, null, Undefined)
Logical assignment with
➢ They can return any data type
AND (&&=)
➢ They can do short circuiting or short circuit evaluation
24.4 Logical nullish
• SHORT-CIRCUITING WITH OR ( || ) assignment (??=)
24.5 Interview Question
In the case of the OR ( || ) operator, short-circuiting means that if the first
operand is a truthy value, it is returned immediately, and the JavaScript
engine does not evaluate the second operand.

Console.log (25 || “Ram”) // output : 25

Console.log ( ‘ ’ || “Ram”) // output : Ram

Console.log (true || 0 ) // output : true

Console.log ( false || “Ram”) // output : Ram

Console.log ( undefined || null ) // output : null

Console.log ( undefined || null || “ ” || 0 || “Ram”) // output : Ram

If the first operand is falsy, the OR (||) operator evaluates and returns
the second operand. However, if the first operand is truthy, it short-
circuits the evaluation by returning that value without checking what
comes after OR. Essentially, it returns the first truthy value it encounters
or, if no truthy value exists, the last operand in the chain—even if it is
falsy.
JavaSCRIPT

Short-circuiting has several practical applications and can be used to optimize code, including simplifying certain
cases where a ternary operator is used.

const account = {};

account.balance = 5000;

account.minimumBalance = 1000;

// Using the ternary operator

const availableBalance1 = account.balance ? account.balance : account.minimumBalance ;

console.log(availableBalance1); // Output: 5000

// Using the logical OR (||) operator

const availableBalance2 = account.balance || account.minimumBalance;

console.log(availableBalance2); // Output: 5000

• SHORT- CIRCUITING WITH AND (&&)

In JavaScript, the && (logical AND) operator returns the first falsy value (i.e, it is short-circuiting on
encountering first falsy value.) it encounters or the last truthy value if all values are truthy.

console.log(25 && "Shyam"); // output : Shyam

console.log( “ “ && "Shyam"); // output : ‘ ’

console.log(true && 0); // output : 0

console.log(false && "Shyam"); // output : false

console.log(undefined && null); // output : undefined

console.log(5 && "Hello" && true && 100); // output : 100

console.log(10 && 0 && "JavaScript"); // output : 0

console.log("JavaScript" && "React" && undefined && "Angular"); // output : undefined

console.log("Frontend" && "Backend" && "Full Stack"); // output : FullStack

const account = {};

account.balance = 5000;

const withdrawalAmount = 2000;

const message = account.balance >= withdrawalAmount && "Withdrawal successful!";

console.log(message); // Output: "Withdrawal successful!"

92 Java Script +91 9662332503 Hornbillcodingsociety@gmail.com


JavaSCRIPT

OR Short-Circuiting (||) AND short-Circuiting (&&)

The OR ( || ) operator returns the first truthy value The AND (&&) operator returns the first falsy value
among all operands or, if all are falsy, it returns the or, if all operands are truthy, it returns the last one.
last operand.

the OR operator is commonly used to set default AND operator to execute code in the second operand
values if the first one is true.

24.2 NULLISH COALESCING OPERATOR

We used the OR (||) operator to set a default value when the first operand is falsy. However, if account.balance
is 0, it is treated as falsy, even though a zero balance is a valid value. Since 0 is falsy, the OR operator mistakenly
replaces it with account.minimumBalance, resulting in an incorrect output of 1000 instead of 0, which may not
be the intended behavior.

In the below example the account balance value could be 0 as account may hold no money

const account = {};

account.minimumBalance = 1000;

account.balance = 0 ;

// Using the logical OR (||) operator

const availableBalance2 = account.balance || account.minimumBalance;

console.log(availableBalance2); // Output: 1000

To correctly handle cases where 0 is a valid value, we should use the nullish coalescing (??) operator instead
of ( || )

const availableBalance2 = account.balance ?? account.minimumBalance ;

console.log(availableBalance2); // Output: 0

The ?? operator considers only null and undefined as nullish values. Unlike ||, it does not treat 0, false, or " "
(empty string) as falsy.

This is because the nullish coalescing operator works based on the concept of nullish values rather than falsy
values. Nullish values include only null and undefined—nothing else.

For the nullish coalescing operator, 0 and "" are not treated as falsy; instead, they are considered valid values,
just like truthy values. However, when encountering a nullish value (i.e., null , undefined ), the operator will
short-circuit the evaluation and return the next operand. That means nullish coalescing checks only for null and
undefined

24.3 LOGICAL ASSIGNMENT OPERATOR

even more modern that the nullish coalescing operator that we just talked about are three new so-called logical assignment
operators that were introduced in ES 2021.

© Hornbill Coding Society +91 9662332503 Hornbillcodingsociety.com 93


JavaSCRIPT

• LOGICAL ASSIGNMENT OPERATOR WITH OR (||=)


Basically logical assignment operator is more optimised version of the OR short circuiting

In the below example the account balance value could be 0 as account may hold no money

const shop1 = {

name: 'Baker’s Delight',

numEmployees: 8,

};

const shop2 = {

name: 'Sweet Treats',

owner: 'Emily Carter',

};

// Using the OR (||) operator to set default values

shop1.numEmployees = shop1.numEmployees || 5; // Output: 8

shop2.numEmployees = shop2.numEmployees || 5; // Output: 5

// Using the OR assignment (||=) operator above code can be optimised

shop1.numEmployees ||= 5; // Output: 8

shop2.numEmployees ||= 5; // Output: 5

• LOGICAL ASSIGNMENT OPERATOR WITH AND (&&=)


In the below example the account balance value could be 0 as account may hold no money
const shop1 = {
name: 'Baker’s Delight',

numEmployees: 8,

};

const shop2 = {

name: 'Sweet Treats',

owner: 'Emily Carter',

};

// Using the AND (&&) operator to set default values

shop1.owner = shop1.owner && “Government owned”; // Output: undefined

shop2.owner = shop2.owner && “Government owned”; ; // Government owned

// Using the AND assignment (&&=) operator above code can be optimised

shop1.owner &&= “Government owned” ; // Output: undefined If the left-hand side is falsy, it remains unchanged.

shop2.owner &&= “Government owned”; // Government owned | The &&= operator assigns a new value only if the existing
value is truthy.

94 Java Script +91 9662332503 Hornbillcodingsociety@gmail.com


JavaSCRIPT

24.4 LOGICAL NULLISH ASSIGNMENT OPERATOR

The above code works well in all situation but if numEmployee = o then it will evaluate to falsy and and in this
case united oputput i.e., 5 is set so to take care of this we have

In the below example the account balance value could be 0 as account may hold no money

const shop1 = {

name: 'Baker’s Delight',

numEmployees: 0,

};

const shop2 = {

name: 'Sweet Treats',

owner: 'Emily Carter',

};

// Using the OR assignment (||=) operator above code can be optimised

shop1.numEmployees ??= 5; // Output: 8

shop2.numEmployees ??= 5; // Output: 5

24.5 INTERVIEW QUESTIONS

• How does short-circuiting work with the OR (||) operator in JavaScript? (Infosys)
• How is short-circuiting different for the AND (&&) operator and OR(||) operator?
• What is the difference between the OR (||) and Nullish Coalescing (??) operators? (Accenture)
• How do logical assignment operators (||=, &&=, ??=) optimize short-circuiting behavior?

© Hornbill Coding Society +91 9662332503 Hornbillcodingsociety.com 95


CHAPTER
Enhanced Object Literals
& Option Chaining
S 25

JavaScript ES6 introduced several enhancements to object literals, Chapter Outline


making code more concise and readable. Features like property
shorthand, method shorthand, computed property names, and the 25.1 Enhanced object literals
spread operator simplify object creation and manipulation. Additionally,
Property shorthand
ES2020 introduced optional chaining (?.), allowing safe access to deeply
Method Shorthand
nested properties without errors, improving code efficiency and
Computed property
robustness.
Merging objects

25.1 ENHANCED OBJECT LITERALS 25.2 Option chaining


Converting to Boolean
ES6 introduced Enhanced Object Literals, making object creation more
Option chaining
concise and improving code readability. These enhancements simplify
25.3 Interview Question’s
object property definition, method declaration, and prototype setting

• PROPERTY SHORTHAND : Previously, when defining an object, we


had to explicitly assign property names to corresponding variables
const name = "Alice";
const age = 25;

const person = {
name: name,
age: age
};

console.log(person); // { name: 'Alice', age: 25 }

With Property Shorthand, if the variable name matches the


property name, we can omit the explicit assignment
const person = {
name,
age
};
console.log(person); // { name: 'Alice', age: 25 }

• METHOD SHORTHAND : Before ES6, defining methods in an object


required the function keyword
JavaSCRIPT

const user = {
greet: function() {
return "Hello!";
}
};

With Method Shorthand, we can omit the function keyword

const user = {
greet() {
return "Hello!";
}
};
console.log(user.greet()); // "Hello!"

• COMPUTED PROPERTY NAMES : we can use square brackets [] to define dynamic property names. we
can now actually compute property names instead of having to write them out manually and literally.

const propName = "status";

const task = {

[propName]: "Completed"

};

console.log(task.status); // "Completed"

We can even use expressions as property names:

const key = "score";

const game = {

["player_" + key]: 100

};

console.log(game.player_score); // 100

Enables dynamic property names. Useful in scenarios like generating object keys dynamically.

• MERGING OBJECTS WITH SPREAD OPERATOR (...) : While not exclusive to Enhanced Object Literals, ES6
introduced the spread operator (...) for cloning and merging objects. Simplifies object merging. Provides
a more readable alternative to Object.assign().

const obj1 = { a: 1, b: 2 };
const obj2 = { b: 3, c: 4 };
const merged = { ...obj1, ...obj2 };
console.log(merged); // { a: 1, b: 3, c: 4 }

© Hornbill Coding Society +91 9662332503 Hornbillcodingsociety.com 97


JavaSCRIPT

25.2 OPTION CHAINING ?.

• Why is it required in the first place : Before optional chaining, accessing deeply nested properties required
multiple checks to avoid errors.
const user = {
profile: {
name: "Alice",
address: {
city: "New York"
}
}
};
// Checking each property manually
if (user && user.profile && user.profile.address) {
console.log(user.profile.address.city);
} else {
console.log("Property does not exist.");
}

• Optional chaining (?.) is a feature introduced in ES2020 that allows safe access to deeply nested object
properties without causing errors if an intermediate property is null or undefined. Instead of throwing an
error, it simply returns undefined. Basically if the property before ?. exists then only the following code is
read and if not undefined will be returned, and exist here follows nullish concept i.e.,property exists if it is
not null or not undefined
const user = {
profile: {
name: "Alice",
address: {
city: "New York"
}
}
};
console.log(user.profile?.address?.city); // "New York"
console.log(user.profile?.contact?.phone); // undefined (no error)

25.3 INTERVIEW QUESTIONS

• Why was optional chaining introduced in JavaScript? What problem does it solve? (Infosys)
• How does optional chaining handle null and undefined values?
• Can we use optional chaining (?.) with arrays? If yes, provide an example.

98 Java Script +91 9662332503 Hornbillcodingsociety@gmail.com


CHAPTER
Set & Map Data
Structure
26

JavaScript ES6 introduced the new data structure to the language. Chapter Outline
Before that JS had only two data structure i.e., Array and Object.

26.1 Sets
26.1 SETS
Key characteristics of set
A set is essentially a collection of unique values, meaning it cannot
Set methods
contain duplicates. This property makes sets useful in various scenarios.
Iterating sets
Additionally, sets can store different data types, and their constructor
Set operation
accepts an iterable. While sets may appear similar to arrays because they
Practical use case
don’t contain key-value pairs, they are iterable just like arrays, there are
some differences as well. Weak set

• KEY CHARACTERISTICS OF SETS 26.2 Map

1. Unique Values: A Set cannot contain duplicate values. If you try to Creating map
Map methods
add a value that already exists, it will be ignored.
Converting array into
2. Order Preservation: Sets maintain the insertion order of elements,
map
meaning the order in which elements are added is preserved.
setting object as key
3. No Indexing: Unlike arrays, Sets do not have indexes. You cannot
Difference between map
access elements using an index.
and object
4. Iterable: Sets are iterable, meaning you can use loops
Weak map
like for...of or methods like forEach to iterate over their elements.
26.3 Data structure to use

// Creating an empty Set 26.4 Interview Question

const mySet = new Set();

// Creating a Set with initial values


const numbers = new Set ([1, 2, 3, 4, 5, 1, 2, 3]); // set(5){1, 2, 3, 4, 5}
const mixedSet = new Set ([1, 'hello', true, { key: 'value' }]);

• SETS METHODS
❖ add(value) : Adds an element to the Set

let set = new Set( );


set.add(10);
set.add(20);
set.add(10); // Duplicate value, will be ignored

console.log(set); // Output: Set(2) {10, 20}


JavaSCRIPT

❖ delete(value) : Removes an element from the Set

set.delete(10);
console.log(set); // Output: Set(1) {20}

❖ has(value) : Checks if a value exists in the Set. Similar to includes method of array

console.log(set.has(20)); // true
console.log(set.has(30)); // false

❖ Size : Returns the number of elements in the Set

console.log(set.size); // Output: 1

❖ clear() : Removes all elements from the Set


set.clear(); console.log(set.size); // Output: 0

• ITERATING OVER A SET


❖ forEach() Method

let cities = new Set ( ["New York", "London", "Paris"] );

cities.forEach(city => {
console.log(city);
});

❖ for...of Loop

for (let city of cities) {


console.log(city);
}

❖ Using the Set Iterator Methods


keys() – Returns an iterator of the values (same as values()).

values() – Returns an iterator of the values.

entries() – Returns an iterator of [value, value] pairs (maintaining compatibility with Maps).

let numbersSet = new Set([10, 20, 30]);

console.log(numbersSet.keys()); // [Set Iterator] { 10, 20, 30 }


console.log(numbersSet.values()); // [Set Iterator] { 10, 20, 30 }
console.log(numbersSet.entries()); // [Set Iterator] { [10, 10], [20,
20], [30, 30] }

• SET OPERATIONS (INTERSECTION, UNION, DIFFERENCE)(ES2025): These operations were previously


performed by writing code manually. However, JavaScript has introduced set operations in ES2025.

100 Java Script +91 9662332503 Hornbillcodingsociety@gmail.com


JavaSCRIPT

❖ Union of Two Sets

let setA = new Set([1, 2, 3]);


let setB = new Set([3, 4, 5]);
let union = new Set([...setA, ...setB]);

union = setA.union(setB)
console.log(union); // Output: Set(5) {1, 2, 3, 4, 5}

❖ Intersection of Two Sets

let setA = new Set([1, 2, 3]);


let setB = new Set([3, 4, 5]);

let intersection = new Set([...setA].filter(x => setB.has(x)));


or we can do
intersection = setA.intersection(setB) (ES2025)

console.log(intersection); // Output: Set(1) {3}

❖ Difference of Two Sets : gives us element present in first one but not in second one. i.e., unique element of set1

let difference = new Set([...setA].filter(x => !setB.has(x)));


or we can do
difference = setA.difference(setB)

console.log(difference); // Output: Set(2) {1, 2}

❖ Symmetric difference : gives us unique element present in the both set . i.e., it is opposite of the intersection

let symmetricDifference = setA.symmetricDifference (setB)


console.log(difference); // Output: Set(2) {1, 2}

❖ Check for disjoint : Checks if one set is completely different from the other.
It gives the Boolean result.

let isDisjoint = setA.isDisjointFrom (setB)


console.log(isDisjoint); // Output: False

❖ Check for subset and superset : Checks for the subset and superset of the sets.

let isSubset = setA.isSubsetOf (setB)


let isSuperset = setA.isSupersetOf (setB)

console.log(isSubset); // Output: False


console.log(isSuperset); // Output: False

© Hornbill Coding Society +91 9662332503 Hornbillcodingsociety.com 101


JavaSCRIPT

• PRACTICAL USE CASES OF SET


❖ Removing Duplicates from an Array

let fruits = ["apple", "banana", "apple", "orange", "banana",


"grape"];
let uniqueFruits = [...new Set(fruits)];
console.log(uniqueFruits); // Output: ['apple', 'banana', 'orange',
'grape']

❖ Checking for the unique element of the array

let names = new Set();


names.add("Alice").add("Bob").add("Alice"); // "Alice" will not be
added again
console.log(names); // Output: Set(2) { 'Alice', 'Bob' }

❖ Efficient lookups
let numSet = new Set([10, 20, 30]);
console.log(numSet.has(20)); // true (fast lookup)

• WEAK SETS : A WeakSet is similar to Set, but:

1. It only stores objects (not primitives).


2. Objects inside a WeakSet are weakly held, meaning they are garbage collected if there are no other
references to them.

let weakSet = new WeakSet();


let obj1 = { name: "Alice" };
let obj2 = { name: "Bob" };
weakSet.add(obj1);
weakSet.add(obj2);

console.log(weakSet.has(obj1)); // true
weakSet.delete(obj1);
console.log(weakSet.has(obj1)); // false

Limitations of WeakSet
• No size property.
• No iteration (forEach, for...of do not work).
• Only supports add(), delete(), and has().

Feature Set WeakSet


Stores only unique values
Supports primitive values (only objects)
Supports iteration
Has size property
Values are garbage-collected

102 Java Script +91 9662332503 Hornbillcodingsociety@gmail.com


JavaSCRIPT

26.2 MAP

A Map in JavaScript is a built-in data structure that allows you to store key-value pairs where:

Keys can be of any data type (unlike objects, where keys are always strings or symbols).
Order is preserved, meaning keys are iterated in the order they were added.
It allows efficient retrieval of values associated with keys.

• CREATING A MAP : Before optional chaining, accessing deeply nested properties required multiple checks
to avoid errors.
let myMap = new Map( );

let userRoles = new Map([


["Alice", "Admin"],
["Bob", "Editor"],
["Charlie", "Viewer"]
]);
console.log(userRoles);
// Output: Map(3) { 'Alice' => 'Admin', 'Bob' => 'Editor', 'Charlie' =>
'Viewer' }

• Map Methods
❖ set(key, value) : Adds or updates a key-value pair

let person = new Map( );


person.set("name", "John");
person.set("age", 30);
person.set("city", "New York");
console.log(person);
// Output: Map(3) { 'name' => 'John', 'age' => 30, 'city' => 'New York' }

In case the property already exit then the property is updated

❖ get(key) : Retrieves the value for a given key

console.log(person.get("name")); // Output: John


console.log(person.get("country")); // Output: undefined (key
does not exist)

❖ has(key) : Checks if a key exists

console.log(person.has("age")); // Output: true


console.log(person.has("salary")); // Output: false

❖ delete(key) : Removes a key-value pair

person.delete("city");
console.log(person);
// Output: Map(2) { 'name' => 'John', 'age' => 35 }

© Hornbill Coding Society +91 9662332503 Hornbillcodingsociety.com 103


JavaSCRIPT

❖ size – Returns the number of key-value pairs

console.log(person.size); // Output: 2

❖ clear() – Removes all key-value pairs

person.clear();
console.log(person.size); // Output: 0

• Converting object into MAP : You can convert a JavaScript object into a Map using the Object.entries()
method. The Object.entries(obj) method returns an array of key-value pairs, which can be directly used to
create a Map.
let obj = {
name : "Alice",
age : 25,
city : "New York"
};
let map = new Map(Object.entries(obj));
console.log(map); // Output: Map(3) { 'name' => 'Alice', 'age' => 25,
'city' => 'New York' }
console.log(map.get("name")); // Output: Alice

• Iterating Over a Map

❖ Using forEach()

let countries = new Map([


["USA", "Washington, D.C."],
["France", "Paris"],
["Japan", "Tokyo"]
]);
countries.forEach((capital, country) => {
console.log(`${country}: ${capital}`);
});
// Output:
// USA: Washington, D.C.
// France: Paris
// Japan: Tokyo

❖ Using for...of Loop

for (let [country, capital] of countries) {


console.log(`${country}: ${capital}`);
}

104 Java Script +91 9662332503 Hornbillcodingsociety@gmail.com


JavaSCRIPT

❖ Using keys(), values(), and entries() : To convert map to an array simply destructure the map we use
[…countries]
• keys() – Returns an iterator of keys.
• values() – Returns an iterator of values.
• entries() – Returns an iterator of [key, value] pairs.

for (let [country, capital] of countries) {


console.log(`${country}: ${capital}`);
}
console.log([...countries.keys()]); // Output: ['USA', 'France',
'Japan']
console.log([...countries.values()]); // Output: ['Washington,
D.C.', 'Paris', 'Tokyo']
console.log([...countries.entries()]); // Output: [['USA',
'Washington, D.C.'], ['France', 'Paris'], ['Japan', 'Tokyo']]

• SETTING OBJECT(ARRAY, FUNCTION) AS AN KEY : we can set object like array or function or object as an key
in the map data structure

let funcMap = new Map();


function greet() { console.log("Hello!"); }
funcMap.set(greet, "Greeting Function");

console.log(funcMap.get(greet)); // Output: Greeting Function

• Differences Between Map and Object


Feature MAP OBJECT

Key Type Any type (objects, numbers, etc.) Only strings or symbols

Keys maintain insertion order No guaranteed order


Order

Iteration Can be directly iterated using for...of or Requires Object.keys(), Object.values(),


forEach() or Object.entries()

Performance Optimized for frequent additions and Less efficient for frequent
deletions modifications

Size Property Has .size to check the number of Requires Object.keys(obj).length


elements

• WeakMap (Special Type of Map) : A WeakMap is similar to Map, except


1. It only allows objects as keys (not primitive values).
2. The objects are weakly held, meaning they get garbage collected when no longer referenced.
3. It does not allow iteration (forEach, keys(), etc.).
4. It only supports set(), get(), has(), and delete().

© Hornbill Coding Society +91 9662332503 Hornbillcodingsociety.com 105


JavaSCRIPT

let weakMap = new WeakMap( );


let obj = { name: "Alice" };

weakMap.set(obj, "Admin");
console.log(weakMap.get(obj)); // Output: Admin
obj = null; // Now the object will be garbage collected

Useful in storing private data for objects (avoiding memory leaks). Caching results while allowing garbage
collection

26.3 DATA STRUCTURE TO USE

We can get data from data written in the programme sourse code itself, from the user interface, API,
irrespective of where data comes from we usually have the collection of data that we need to store the
received data in the one of the four data

arrays set Object Map

Store data sequentially, When working The standard data More versatile than
allowing for duplicate exclusively with unique structure in JavaScript. objects, as keys can be
entries. values. of any data type.
Preferred when the
key's value is an object. Use when keys are not
limited to strings or
symbols.

When data High performance is Easier to define and Simple to define,


manipulation is required access the value with . access, and iterate over.
required. and []

26.4 INTERVIEW QUESTIONS

• What are the key differences between a Set and an Array in JavaScript? When would you prefer using a Set
over an Array? (Infosys, most common question almost asked in every interview)
• How do Map and Object differ in JavaScript, and in which scenarios would you choose one over the other?
(Mindtree, Pesrsistant systems, cognizant, one of the most common question)
• What is a WeakSet and WeakMap in JavaScript? How do they differ from regular Set and Map, and why are
they useful?
• How can you use a Set to remove duplicate elements from an array? Provide a code example.

106 Java Script +91 9662332503 Hornbillcodingsociety@gmail.com


String Properties &
CHAPTER

27
Methods
Strings in JavaScript are sequences of characters used for text Chapter Outline
manipulation. They are immutable but come with various built-in
methods for accessing, modifying, and transforming text. This chapter 26.1 String properties
covers string properties, methods, and operations like searching,
Bracket notation property
replacing, splitting, joining, and formatting text efficiently.
length property

27.1 STRING PROPERTIES 26.2 String methods


IndexOf ()
We can access the index property and length property of the string
lastIndexOf ()

const carBrand = “Rolls Royce car” charAt()

const model = “Phantom6700” slice ()

const carPrice = 15,499 $ change case of string


trim (), trimStart(),End()

// Creating Accessing the element of the string replace (), replaceAll()

console.log(carBrand[0]) // R includes(), startWith(),

console.log(model [7]) // 6 but string endsWith()

console.log(“Ferrary”[4]) // a split ()

console.log(“Ferrary”.length) // 6 join()
padStart ()
27.2 STRING METHODS padEnds()
repeat()
❖ Index OF : Access the index of the passed string, this gives us the first
26.3 Interview Question
instance of occurance of letter in a string. If the string character is
absent the -1 is returned.

console.log(carBrand.indexOf [ ‘o’ ]) // Output: 1

console.log(carBrand.indexOf [ ‘Rolls’ ]) // Output: 0

console.log(carBrand.indexOf [ ‘x’ ]) // Output: -1

❖ lastIndexOf : Gives us the last occurance of the letter in a string.

console.log(carBrand.lastIndexOf [ ‘o’ ]) // Output: 7

❖ charAt(index)
console.log(carBrand.charAt (2)) // Output: l
JavaSCRIPT

❖ Slice(x, y) : used for extracting the part of string(substring) X = extraction starts at index, y = extraction ends but
not inclusive of Y index this is non destructive meaning original string is not changed. String is primitive so
impossible to mutate them. slice(start, end)

Note: The length of the extracted string = ( last index – first index)

console.log(carBrand.slice (2)) // Output: lls Royce car

console.log(carBrand.slice (2, 7)) // Output: lls R

console.log(carBrand.slice (-2)) // Output: ar extrct the last part

console.log(carBrand.slice (2, -1)) // Output: lls Royce ca extrct the


last part

// extracting the first word without knowing the lengrh of the string

console.log(carBrand.slice (0, (carBrand.indexOf( “ ”) ))) //


Output: Rolls

// extracting the last word without knowing the lengrh of the string

console.log(carBrand.slice ((carBrand.lastIndexOf( “ ”) +1) )) //


Output: car +1 for removing the space as first index is included

Note: Strings in JavaScript are primitive values, so logically, they shouldn't have methods like objects do.
However, JavaScript handles this intelligently.

Whenever a method is called on a string, JavaScript automatically converts the string


primitive into a temporary String object with the same content. The method is then executed on
this object.

This process is known as "boxing", as it temporarily wraps the primitive value inside an object
(a "box") to provide access to methods. Once the method execution is complete, the object
disappears, and the string is converted back to primitive.

Behind the scence console.log(new string (“Ram”)) // String {‘Ram’} i.e., Object

❖ Change the case of string

console.log(carBrand.toUpperCase); //Output: ROLLS ROYCE CAR


console.log(carBrand.toLowerCase); //Output: rolls royce car

❖ trim() : Removes all empty spaces from the string.

console.log(carBrand.trim()); // Output: RollsRoyceCar


console.log(carBrand.trimStart); // Output: Rolls Royce Car trim
the white space at the start of the string.(ES2019)

console.log(carBrand.trimEnd); // Output: Rolls Royce Car trim


the white space at the start of the string. (ES2019)

108 Java Script +91 9662332503 Hornbillcodingsociety@gmail.com


JavaSCRIPT

❖ replace() and replaceAll() : replace part of string on first occurance and all the occurance
replace(searchValue, replaceValue), replaceAll(searchValue, replaceValue) (ES2021)

const carPrice = “15,499 $”


console.log(carPrice.replace (‘$’ , '₹’ ).replace(‘ ,’ , “ | ”); // output: 15
| 499 ₹

console.log(carBrand.replaceAll(‘ ’, ‘&’)); // Output: olls&Royce&Car

❖ Includes(), StartsWith(), endsWith() method

console.log(Model.includes(6700)); // Output: True


console.log(Model.startsWith(‘Pha’)); // Output: True
console.log(Model.endsWith(6)); // Output: false

❖ Split(seperator) : split the string based on the given saperator in the method

console.log(carBrand.split()); //Output: ["Rolls Royce car"]


console.log(carBrand.split(" ")); //Output: ["Rolls", "Royce", "car"]

❖ Join(joiner) : join the element of array based on the given joiner in the method

console.log( ["Rolls Royce car"].join(‘+’)); //Output: Rolls+Royce


+car

❖ padStart() and padEnd() : add padding at the beginning and end of the string making it of desired length

console.log(carBrand.padStart( 20, &)); //Output: &&&&&Rolls


Royce Car

console.log(carBrand.padEnd( 30, $)); //Output: Rolls Royce


Car$$$$$$$$$$$$$$$

❖ repeate () : let us repeate the same string multiple times

const loading = "🔄 Loading... ";


console.log(loading.repeat(5)); //Output: 🔄 Loading... 🔄 Loading...
🔄 Loading... 🔄 Loading... 🔄 Loading...

27.3 INTERVIEW QUESTIONS

• How can you remove leading and trailing spaces from a string? (Infosys)
• How do you make reverse of string ? (Mindtree, Pesrsistant systems, cognizant, one of the most common
question)
• Reverse the order of the words of string (Most common question )
• Reverse the each word of the string while keeping the order of the words intact! (Most common question )

© Hornbill Coding Society +91 9662332503 Hornbillcodingsociety.com 109


CHAPTER
Function Methods
28
Call, Apply, Bind

In programming, there are times when we need to convert data from Chapter Outline
one type to another. JavaScript offers two approaches for this: Type
conversion and Type coercion. In the chapter 11 we saw the 28.1 Default parameter
introduction to the function where we discussed the basics of defining
Default parameter
function, types of function and calling function. In this chapter we are
Primitive vs. Referene
going to gain the advanced knowledge about the functions type
Pass by value vs. pass by
28.1 DEFAULT PARAMETER reference

sometimes it's useful to have functions where some parameters are set Higher order function
Abstraction in higher
by default. This way we do not have to pass them in manually in case we
order function
don't
String coercion
28.2 Methods of function
'use strict';
Call ()
const orders = [ ]; Apply ()

const placeOrder = function (itemName, quantity = 1, pricePerUnit Bind ()

= 0) { 28.3 Interview Questions

const order = {

itemName,

quantity,

totalPrice: quantity * pricePerUnit,

};

console.log(order);

orders.push(order);

};

placeOrder('Laptop', 2, 50000); // output : { itemName: 'Laptop',


quantity: 2, totalPrice: 100000 }

placeOrder('Laptop'); // output : { itemName: 'Laptop', quantity: 1,


totalPrice: 0}
JavaSCRIPT

If we don’t set default values for function parameters, and we call the function without passing all arguments,
the missing parameters will be undefined.

However, if we set default values in the function definition, those default values will be used when no argument
is provided for that parameter. An even more useful feature is that we can use the values of previously defined
parameters as defaults for later parameters.

• PARAMETER : PRIMITIVE VS. REFRENCE TYPE : primitives and objects work differently in the context of
functions.

'use strict';

// Define a booking object

const booking = {

passengerName : 'Alice Johnson',

ticketNumber : 56789

};

// Function that modifies the booking object Passing object as an parameter

const processBooking = function (ticket, traveler) {

ticket = 99999; // This won't affect the original ticket number

traveler.passengerName = 'Ms. ' + traveler.passengerName; // This will


modify the original object

};

processBooking(booking.ticketNumber, booking);

console.log(booking.ticketNumber); // Still 56789, as primitive values are


passed by value

console.log(booking.passengerName); // "Ms. Alice Johnson", as objects are


passed by reference (actually passed by value but value contains the
reference to location in the memory)

When we pass an object to a function, we are not passing the object itself but rather a reference to its
location in memory. This means that if we modify the object inside the function, the changes will persist
outside the function as well. Both the original variable and the function parameter point to the same memory
location.

On the other hand, when we pass a primitive value (e.g., number or a string) to a function, JavaScript creates a
copy of that value. Any changes made to this copy inside the function do not affect the original value outside the
function.

© Hornbill Coding Society +91 9662332503 Hornbillcodingsociety.com 111


JavaSCRIPT

Pass-by-Value vs. Pass-by-Reference

In programming, two common terms describe how function arguments are handled: pass-by-value and pass-by-
reference. JavaScript, however, does not support true pass-by-reference. Instead, it always uses pass-by-
value, even when dealing with objects.

• Primitives (e.g., numbers, strings, booleans) → Passed by value (a copy is created, and modifications do not
affect the original).

• Objects (e.g., arrays, functions, objects) → Passed by value, but the value itself is a reference to the object
in memory. This makes it appear as if JavaScript is using pass-by-reference, but in reality, it is still passing
the reference by value. And not the pass by reference itself.

In contrast, languages like C++ support true pass-by-reference, where a reference to the original value (even for
primitives) is passed to the function, allowing direct modification of the original variable.

• HIGHER ORDER FUNCTION

First-Class Functions in JavaScript

o Definition: JavaScript supports first-class functions, meaning functions are treated as values.

Functions as Values: Since functions are a type of object, they can be:

Stored in variables Stored in object property Passed as arguments to Returned from other
other functions functions

const greet = function() { const obj = { function execute(fn) { function outer() {

console.log("Hello, sayHello: function() { fn(); return function() {


World!"); console.log("Hi!"); } console.log("Returned
} function called!");
}; }; execute(greet); // Output: };
greet(); // Output: Hello, obj.sayHello(); // Output: Hello, World! }
World! Hi! const newFunc = outer();
newFunc(); // Output:
Returned function called!

Higher-Order Functions : A higher-order function is a function that:

Accepts another function as an argument Returns another function

function multiplier(factor) {
function operate(x, y, operation) {
return function(num) {
return operation(x, y); return num * factor;
} };
}
function add(a, b) { return a + b; }
const double = multiplier(2);
console.log(operate(5, 3, add)); // Output: 8 console.log(double(4)); // Output: 8

112 Java Script +91 9662332503 Hornbillcodingsociety@gmail.com


JavaSCRIPT

JavaScript allows higher-order functions because it has first-class functions. i.e., function can be stored as value.

Difference Between First-Class and Higher-Order Functions

• First-Class Functions: . First-class functions are a language feature where functions are treated as values,
meaning they can be assigned to variables, passed as arguments, or returned from other functions. However,
this is just a concept, not something that exists in practice.

• Higher-Order Functions: on the other hand, are real functions that either take other functions as arguments
or return them. They are possible because JavaScript supports first-class functions.

Simply put, first-class functions define a capability, while higher-order functions are practical applications
of that capability.

Function Methods : Since functions are objects, they also have methodsl like other object in JS, such as: bind(),
call(), apply() e.t.c and Other function methods that enhance functionality

• Abstraction in Higher order function

// Function that capitalizes every word in a sentence

const capitalizeWords = function (sentence) {

return sentence

.split(' ')

.map(word => word.charAt(0).toUpperCase() + word.slice(1))

.join(' ');

};

// Higher-order function that takes a string and a transformation function

const modifyString = function (text, operation) {

console.log(`Original text: ${text}`);

console.log(`Modified text: ${operation(text)}`);

console.log(`Transformation applied by: ${operation.name}`);

};

// Calling the higher-order function with a callback

modifyString("hello world from javascript", capitalizeWords);

Callback functions in JavaScript improves code reusability and modularity by allowing functions to be broken
into smaller, independent parts. This makes code more organized, maintainable, and easier to debug.

More importantly, callbacks enable abstraction, a fundamental programming concept that hides
implementation details, allowing us to focus on the bigger picture. In our example, the modifyString function

© Hornbill Coding Society +91 9662332503 Hornbillcodingsociety.com 113


JavaSCRIPT

does not handle string transformation itself. Instead, it delegates this task to a callback function, making it
flexible and reusable for different transformations.

Since modifyString operates at a higher level of abstraction, it is considered a higher-order function, while the
transformation function handles lower-level details. This separation of concerns allows for scalable and
adaptable code, where different transformation functions can be passed in without modifying the core logic.
By leveraging callback functions and higher-order functions developers can write cleaner, more efficient, and
future-proof code.

28.2 METHODS OF FUNCTIONS

In Java script data type of function is object and we already know that objects have method of their own so
function too have their own methods like call(), apply(), bind(). These methods available on functions that allow
us to control the this context explicitly. These methods are particularly useful for borrowing methods from one
object to another.
• CALL METHOD : Built-in function in JavaScript that allows you to invoke a function with a specific this value
and pass arguments individually. It is commonly used to borrow methods from other objects or explicitly set
the context of this.

const hertz = {
company : 'Hertz',
locationCode : 'HZ',
reservations : [ ],
rentCar( carType, customerName) {
console.log(`${customerName} rented a ${carType} from ${this.company}.`);
this.reservations.push({ carType, customerName });
}
};
const avis = {
company : 'Avis',
locationCode : 'AV',
reservations : [ ]
};
const rent = hertz.rentCar;

rent( 'SUV', 'Alice Johnson') // this does not work as this in this context is undefined because this is simple function
and not a method attached to any object or not been called upon any object.

// Using call() to set 'this' explicitly

rent.call( avis, 'SUV', 'Alice Johnson'); // Alice Johnson rented a SUV from Avis.
console.log(avis); // { company: 'Avis', locationCode: 'AV', reservations: [ { carType: 'SUV', customerName: 'Alice
Johnson' } ]}
rent.call( hertz, 'Sedan', 'Bob Williams'); // Bob Williams rented a Sedan from Hertz.
console.log(hertz); // { company: 'Hertz', locationCode: 'HZ', reservations: [ { carType: 'Sedan', customerName:
'Bob Williams' } ] }

114 Java Script +91 9662332503 Hornbillcodingsociety@gmail.com


JavaSCRIPT

• APPLY METHOD : Similar to the call method; apply method is used to invoke functions with a specified this
context. The primary difference is in how they handle function arguments:

• call Method: Accepts arguments individually after the this value.

• apply Method: Accepts arguments as an array or array-like object.

functionName.apply ( thisArg, [argsArray] );

// Using apply() to set 'this' explicitly

rent.apply (avis, ['SUV', 'Alice Johnson']); // Alice Johnson rented a SUV from Avis.

console.log(avis); // { company: 'Avis', locationCode: 'AV', reservations: [ { carType: 'SUV', customerName: 'Alice
Johnson' } ]}

rent.apply ( hertz, ['Sedan', 'Bob Williams']); // Bob Williams rented a Sedan from Hertz.

console.log(hertz); // { company: 'Hertz', locationCode: 'HZ', reservations: [ { carType: 'Sedan', customerName: 'Bob
Williams' } ] }

This example demonstrates how the apply method can be used to invoke a function with a specific this value
and arguments provided as an array. While the apply method is useful, it's worth noting that in modern
JavaScript, the spread operator (...) offers a more concise and readable alternative for passing arguments.
However, understanding apply is beneficial for working with legacy code or specific use cases.

// Using the spread operator to set 'this' explicitly

rent.call(avis, ...['SUV', 'Alice Johnson']);

console.log(avis);

• BIND METHOD : just like the call method, bind also allows us to manually set this keywords for any function
call. The bind method creates a new function that, when invoked, has it’s this keyword set to the provided
value. Unlike call or apply, bind does not immediately execute the function but returns a new function
with the specified this context where this keyword is bound. We can also set default parameters in advance
when using bind, which essentially involves pre-defining certain arguments beforehand. This approach
follows a common pattern called partial application, where some of the original function's arguments are
pre-applied.

// Using the spread operator to set 'this' explicitly

rent.call(avis, ...['SUV', 'Alice Johnson']);

console.log(avis);

const rentForAvis = hertz.rentCar.bind(avis);

const rentForHertz = hertz.rentCar.bind(hertz);

// Using the bound functions

© Hornbill Coding Society +91 9662332503 Hornbillcodingsociety.com 115


JavaSCRIPT

rentForAvis('SUV', 'Alice Johnson'); // Alice Johnson rented a SUV from Avis.

console.log(avis); { company: 'Avis', locationCode: 'AV', reservations: [ { carType: 'SUV', customerName: 'Alice Johnson'
} ]}

rentForHertz('Sedan', 'Bob Williams'); // Bob Williams rented a Sedan from Hertz.

console.log(hertz); // { company: 'Hertz', locationCode: 'HZ', reservations: [ { carType: 'Sedan', customerName: 'Bob
Williams' } ]}

28.3 INTERVIEW QUESTIONS

• What is the difference between call(), apply(), and bind() methods in JavaScript? (Infosys, TCS, Wipro,
Accenture, almost asked in every interview)
• What is the advantage of using default parameters in JavaScript functions, and how can previously defined
parameters be used as defaults?
• How does JavaScript handle function parameters, and what is the difference between passing primitives and
objects?
• Explain first-class functions and higher-order functions in JavaScript with examples.

116 Java Script +91 9662332503 Hornbillcodingsociety@gmail.com


IFFE & Closures
CHAPTER

29

JavaScript offers powerful features like Immediately Invoked Function Chapter Outline
Expressions (IIFE) and Closures, which enhance encapsulation,
prevent global scope pollution, and maintain data privacy. 29.1 Immidiately invoked
These concepts are essential for mastering JavaScript, forming the function expression(IIFE)
foundation of event handling, callbacks, and functional programming, Types of IIFE

making them crucial for writing efficient and modular JavaScript code. Anonymous IIFE
Named IIFE
29.1 IMMIDIATELY INVOKED FUNCTION EXPRESSION Arrow function IIFE

An Immediately Invoked Function Expression (IIFE) is a JavaScript Paramateriased IIFE


IIFE with returned value
function that runs as soon as it is defined. It is a design pattern often
Use case of IIFE
used to create a private scope and avoid polluting the global namespace.
Advantages of IIFE

(function () { 29.2 Closures


How closures work
. // Code inside IIFE
Use cases of closures
}) (); Function passed inside a parentheses, treated as Advantages of closures
function expression & () infront of parentheses
or 29.3 Interview Questions
ensures that function is invoked immediately.
(() => {

// Code inside IIFE

})();

Function Definition: The function is defined inside parentheses. This


ensures the function is treated as an expression. If we omit the
parentheses, JavaScript treats it as a function declaration, which
requires a function name.

Types of IIFE vhb

• Anonymous IIFE : A function without a name that executes


immediately.

(function ( ) {

console.log("This is an anonymous IIFE.");

})(); // This is an anonymous IIFE


JavaSCRIPT

• Named IIFE: An IIFE with a function name, which helps in debugging.

(function myFunction() {

console.log("This is a named IIFE.");

})(); // This is a named IIFE.

• Arrow function IIFE: An IIFE with a function name, which helps in debugging.

(() => {

console.log("This is an arrow function IIFE.");

})(); // This is an arrow function IIFE.

• Parameterized IIFE : Passing parameters to an IIFE.

(function (name) {

console.log("Hello, " + name);

})("Anuradha"); // Hello Anuradha

• IIFE with return value : Passing parameters to an IIFE.

const result = (function () {

return "Returned from IIFE";

})();

console.log(result); // Returned from IIFE

Use case of IFFE vhb

• Avoid Global Namespace Pollution: IIFEs help prevent variables from leaking into the global scope.

(function () {

var message = "Hello, World!";

console.log(message);

})();

console.log(typeof message); // Undefined (not accessible outside IIFE)

• Encapsulation and Data Privacy : IIFEs can be used to create private variables and functions.

118 Java Script +91 9662332503 Hornbillcodingsociety@gmail.com


JavaSCRIPT

const counter = (function () {

let count = 0; // Private variable

return {

increment : function () {

count++;

console.log(count);

},

Decrement : function () {

count--;

console.log(count);

};

})();

counter.increment(); // 1

counter.increment(); // 2

counter.decrement(); // 1

• Avoiding Conflicts in Modules : can be used to isolate code in different scripts, preventing variable conflicts.

(function () {

const localVar = "I am local";

console.log(localVar);

})(); // Undefined Another variable with localVar can be used in the


programme as IFFE creates the private variable.

IFFE are useful for working with the Ajax, Asynchronous JS and sever connection operation e.t.c.

Advantages of IFFE

Helps in modular programming.

Provides encapsulation and data privacy.

Avoids variable hoisting issues.

Useful in async programming.

29.2 CLOSURES

A closure is a function that remembers the variables from its lexical scope even when it is executed outside that scope.

© Hornbill Coding Society +91 9662332503 Hornbillcodingsociety.com 119


JavaSCRIPT

In simpler terms, a closure allows a function to access variables from its parent function even after the parent
function has finished executing.
Closures are one of the most powerful and commonly used features in JavaScript, especially in functional
programming and event handling.
function outerFunction() {

let outerVariable = "I am from outer function";

function innerFunction() {

console.log(outerVariable); // Inner function can access outerVariable

return innerFunction;

const closureFunc = outerFunction(); // outerFunction is called and returns innerFunction

closureFunc(); // Output: "I am from outer function"

When outerFunction is executed, it creates a local variable outerVariable and defines innerFunction, which
references outerVariable. Normally, when a function finishes execution, its execution context is removed from
the call stack, and its variables are garbage collected. However, in this case, innerFunction is returned and
assigned to closureFunc, which preserves access to outerVariable. Since closureFunc still references
outerVariable, JavaScript moves the variable environment to the heap instead of clearing it from memory. This
mechanism, known as a closure, ensures that innerFunction can still access outerVariable, even after
outerFunction has executed.

Note: if an object is reachable by a closure, it cannot be garbage collected and will therefore stay in the
heap indefinitely.

Explaination

o outerFunction has a local variable outerVariable.

o innerFunction is defined inside outerFunction, so it has access to outerVariable.

o When outerFunction is executed, it returns innerFunction.

o Even though outerFunction has finished executing, closureFunc (which holds innerFunction) still remembers
the value of outerVariable.

o This behavior is what we call a closure—a function "remembering" the scope it was created in.

• How Closures Work in JavaScript : Closures work due to JavaScript’s lexical scoping.

When a function is created inside another function, it forms a scope chain. The inner function retains access
to the variables and parameters of the outer function, even after the outer function has completed
execution.

120 Java Script +91 9662332503 Hornbillcodingsociety@gmail.com


JavaSCRIPT

function outer(a) {

return function inner(b) {

return a + b; // 'inner' remembers 'a' from 'outer'

};

const addFive = outer(5);

console.log(addFive(3)); // Output: 8

console.log(addFive(10)); // Output: 15

Use case of closures

• Data Encapsulation & Private Variables : count is accessible only within the returned object. It cannot be
modified directly, ensuring data privacy.

function counter() {

let count = 0; // Private variable

return {

increment : function () {

count++;

console.log(count);

},

decrement : function () {

count--;

console.log(count);

};

const myCounter = counter();

myCounter.increment(); // 1

myCounter.increment(); // 2

myCounter.decrement(); // 1

console.log(myCounter.count); // Undefined (Cannot access count directly)

© Hornbill Coding Society +91 9662332503 Hornbillcodingsociety.com 121


JavaSCRIPT

• USING CLOSURES IN SETTIMEOUT : Here, the arrow function inside setTimeout remembers the message
variable from delayedMessage even after delayedMessage has executed.

function delayedMessage(message, delay) {

setTimeout(() => {

console.log(message);

}, delay);

delayedMessage("Hello after 2 seconds", 2000);

• FUNCTION FACTORIES (GENERATING FUNCTIONS DYNAMICALLY) : Closures allow us to create functions


dynamically with predefined behavior.

function multiplier(factor) {

return function (number) {

return number * factor;

};

const double = multiplier(2);

const triple = multiplier(3);

console.log(double(4)); // Output: 8

console.log(triple(4)); // Output: 12

Advantages of closures

Encapsulation : Provides data privacy by keeping variables within a function’s scope.


Modular Code : Helps create function factories and maintainable code.
Asynchronous Programming : Helps manage state in callbacks and setTimeout.
Functional Programming : Essential for implementing functional programming concepts

29.3 INTERVIEW QUESTIONS

• What is an Immediately Invoked Function Expression (IIFE) in JavaScript? Explain with examples.
• How do closures work in JavaScript, and why do they prevent garbage collection of variables?( almost asked
in every interview)
• What is closures in JS ? ?(Stupa analytics, Infosys, Congnizant, Accenture e.t.c)
• What are the advantages of using closures? Provide real-world use cases.

122 Java Script +91 9662332503 Hornbillcodingsociety@gmail.com


Array Methods
CHAPTER

30

Arrays are vital in JavaScript, and mastering advanced methods like Chapter Outline
forEach(), map(), filter(), reduce(), find(), some(), and every() is key.
These tools help you transform and analyze data efficiently, write 30.1 Array methods
cleaner logic, and solve real-world problems with more expressive and 30.2 Map method
readable code. 30.3 Filter method
30.4 Reduce method
30.1 AT METHODS
30.5 Find method
• The .at() method in JavaScript is used to access elements of an FindIndex method

array, string, or typed array using a relative index. It allows both 30.6 Find last & FindLastIndex

positive and negative indices, Supports negative indexing (unlike 30.7 Some and every method

array[index]). 30.8 Flat and FlatMap method


30.9 Sort Method
Improves readability when accessing the last few elements of an
30.10 Array Grouping
array. e.g., we could get last element either by
30.11 Other Array Method
console.log(numbers[numbers.length – 1]); or
Fill method
console.log(numbers.slice(-1)[0]);
Array.From
with slice(-1) we get last element copy array with [0] we get last
30.12 Non destructive method
element.
toReversed

let numbers = [10, 20, 30, 40, 50]; toSpliced


With
console.log(numbers.at(2)); // Output: 30
30.13 Interview Questions
console.log(numbers.at(-1)); // Output: 50 (last element)

30.2 MAP METHOD

The map() method is a built-in function in JavaScript used to transform


arrays. It creates a new array by applying a callback function to each
element of an existing array. Unlike the forEach() method, which simply
executes a function on each element, map() returns a new array with
modified values.

Syntax

const newArray = array.map(callback(currentValue, index, array));


JavaSCRIPT

• BASIC EXAMPLE :

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

const squaredNumbers = numbers.map(num => num * num);

console.log(squaredNumbers); // [1, 4, 9, 16]

console.log(numbers); // [1, 2, 3, 4] (Original array remains unchanged)

• Mapping an Array of Objects:

const users = [

{ firstName: "Alice", lastName: "Johnson" },

{ firstName: "Bob", lastName: "Smith" },

];

const fullNames = users.map(user => `${user.firstName} ${user.lastName}`);

console.log(fullNames); // ["Alice Johnson", "Bob Smith"]

• Using index parameter :

const prices = [100, 200, 300];

const withTax = prices.map((price, index) => `Item ${index + 1}: $${price * 1.1}`);

console.log(withTax);

// ["Item 1: $110", "Item 2: $220", "Item 3: $330"]

30.3 FILTER

The filter() method creates a new array containing only the elements that satisfy a given condition. It does not
modify the original array.

array.filter(callback(element, index, array), thisArg);

• FILTER METHOD AT WORK :

const numbers = [10, 25, 30, 45, 50];

const greaterThan30 = numbers.filter(num => num > 30);

console.log(greaterThan30); // [45, 50]

• WORKING WITH ARRAY OF OBJECT :

const students = [

{ name: "Alice", marks: 85 },

{ name: "Bob", marks: 45 },

124 Java Script +91 9662332503 Hornbillcodingsociety@gmail.com


JavaSCRIPT

{ name: "Charlie", marks: 92 },

{ name: "David", marks: 30 }

];

const passedStudents = students.filter(student => student.marks >= 50);

console.log(passedStudents); // [{ name: "Alice", marks: 85 }, { name: "Charlie", marks: 92 }]

• FILTERING SPECIFIC VALUES : You can use filter() to remove unwanted values from an array. e.g.,- null undefined
or false.

const mixedArray = [10, 0, null, "hello", false, 42, undefined, "JavaScript", "", NaN];

const filteredArray = mixedArray.filter(item => item); // keeps only truthy value

console.log(filteredArray); // [10, "hello", 42, "JavaScript"] eliminate all the falsy value i.e., - Null, NaN, undefined,
“ ”, 0, False

• FILTERING UNIQUE VALUES : You can remove duplicate values using filter() and Set.

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

const uniqueNumbers = numbers.filter((value, index, arr) => arr.indexOf(value) === index);

console.log(uniqueNumbers); // [1, 2, 3, 4, 5, 6]

30.4 REDUCE

The reduce() method in JavaScript is a powerful array method used to process and accumulate values in an array
into a single result. It is commonly used for summing numbers, flattening arrays, counting occurrences, and more.
Returns a single value that results from accumulating all elements.

Syntax : array.reduce(callback(accumulator, currentValue, index, array), initialValue);

callback – A function that runs on each element of the array.


• accumulator – Stores the accumulated result of previous iterations.
• currentValue – The current element being processed.
• index (optional) – The index of the current element.
• array (optional) – The original array being reduced.
initialValue (optional) – The starting value of the accumulator.
• If provided, the accumulator starts with this value.
• If not provided, the first element of the array is used as initialValue, and iteration
starts from the second element.

• REDUCE AT WORK

© Hornbill Coding Society +91 9662332503 Hornbillcodingsociety.com 125


JavaSCRIPT

const numbers = [10, 20, 30, 40];

const sum = numbers.reduce((acc, num) => acc + num, 0);

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

The accumulator (acc) starts at 0 (the initialValue) and adds each element to it.

Practical use case of reduce includes Summing the elements of an array, finding the maximum value of array,
keeping track of occurance of an elements, flattning an array, grouping elements by properties.

• REDUCERIGHT : works like reduce() but processes the array from right to left

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

const result = numbers.reduceRight((acc, num) => acc - num);

console.log(result); // Output: -2 (1 - (2 - (3 - 4)))

• CHAINING METHODS : these methods can be chained together to get the final output.

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

const doubled = numbers.map(n => n * 2); // [2, 4, 6, 8, 10, 12]

const evens = doubled.filter(n => n % 2 === 0); // [2, 4, 6, 8, 10, 12] (all remain)

const sum = evens.reduce((acc, n) => acc + n, 0); // 42

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

or we can chain them together in one line

const sum = [1, 2, 3, 4, 5, 6].map(n => n * 2).filter(n => n % 2 === 0).reduce((acc, n) => acc + n, 0);

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

If we can do whatever we can do with map filter and reduce then why not use the for each method.

Feature forEach() map(), filter(), reduce()

Return Value Does not return a value (returns undefined) All return new data (a new array or value)

Chaining Cannot be chained as it returns undefined, Can be chained directly, allowing cleaner
requiring an external variable and more functional code

Performance Less optimized and can be slower in certain Generally faster due to functional
scenarios programming optimizations

Use Case Used for side effects (e.g., updating Encourage pure functions (no side effects,
variables, logging, modifying DOM) just data transformation)

When you need to perform actions on each When you want to transform, filter, or
When to Use
element without returning a new result reduce data to a new structure or value

126 Java Script +91 9662332503 Hornbillcodingsociety@gmail.com


JavaSCRIPT

30.5 FIND METHOD

The find() method is a built-in JavaScript function that allows you to search for an element in an array based on
a given condition. It returns the first element that satisfies the condition; if no element matches, it returns
undefined.

Syntax : array.find(callback(element, index, array), thisArg)

Parameters
• callback: A function that is executed for each element in the array.
o element: The current element being processed.
o index (optional): The index of the current element.
o array (optional): The array on which find() is called.

• thisArg (optional): A value to use as this when executing the callback function.

Example

const numbers = [1, 3, 7, 8, 10, 15];

const firstEven = numbers.find(num => num % 2 === 0);

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

The major difference between the filter and find is filter return all the element satisfying the condition and
returns a new array find on the other hand returs only first instance of occurance and dosen’t return the new
array

• FINDINDEX METHOD

The findIndex() method works similarly to find(), but instead of returning the element itself, it returns its
index. If no element matches the condition, it returns -1.

Syntax - array.findIndex(callback(element, index, array), thisArg);

const numbers = [3, 7, 12, 19, 21, 24];

const evenIndex = numbers.findIndex(num => num % 2 === 0);

console.log(evenIndex); // Output: 2

30.6 FIND LAST AND FIND LAST INDEX

Both methods are used to search arrays from the end (right to left), introduced in ES2023. They are
counterparts of find() and findIndex() which search from the start (left to right).

• FINDLAST() : find the lass element that satisfies the condition given in the call back function

© Hornbill Coding Society +91 9662332503 Hornbillcodingsociety.com 127


JavaSCRIPT

Syntax - arr.findLast(function callbackFn(element, index, array) { ... } , thisArg])

const numbers = [5, 12, 50, 130, 44];

const result = numbers.findLast(num => num > 45);

console.log(result); // 130 (last number > 45)

• FINDLASTINDEX : Returns the index of the last element in the array that satisfies the provided testing
function.

Syntax - arr.findLastIndex(function callbackFn(element, index, array) { ... } , thisArg])

const numbers = [5, 12, 50, 130, 44];

const result = numbers.findLastIndex(num => num > 45);

console.log(result); // 3

30.7 SOME AND EVERY METHOD

• SOME () method checks if at least one element in the array passes the test implemented by the
provided callback function.

Syntax : arr. some(function callbackFn(element, index, array) { ... } , thisArg])

const users = [

{ name: 'Amit', active: false },

{ name: 'Sara', active: true },

];

const isAnyUserActive = users.some(user => user.active);

console.log(isAnyUserActive); // true

• EVERY( ) : method checks if all elements in the array pass the test implemented by the provided function. it
returns true if all elements satisfy the condition and returns false if any one of the element does not.

128 Java Script +91 9662332503 Hornbillcodingsociety@gmail.com


JavaSCRIPT

Syntax - arr. every(function callbackFn(element, index, array) { ... } , thisArg])

const products = [

{ name: 'Pen', inStock: true },


{ name: 'Notebook', inStock: true },
];
const allAvailable = products.every(product => product.inStock);

console.log(allAvailable); // true

30.8 FLAT AND FLAT MAP METHOD

• FLAT ( ) : creates a new array by flattening nested arrays up to the specified depth

Syntax : arr.flat(depth) depth (optional): Specifies how deep a nested array structure should be
flattened. Default is 1

Let’s assume that each parcel contains many other parcel wrpped in it.

const parcels = [1, 2, [3, 4], [5, [6, 7]]];

const unpacked = parcels.flat(); // Default depth = 1

const deepUnpacked = parcels.flat(2); // depth = 2

console.log(unpacked); // Output: [1, 2, 3, 4, 5, [6, 7]]

console.log(deepUnpacked); // Output: [1, 2, 3, 4, 5, 6, 7]

• FLATMAP () : first maps each element using a mapping function, then flattens the result by one level.
Basically it is combination of map and flat.

Syntax : arr.flatMap(callback)

const sentences = ["hello world", "javascript is fun"];

const words = sentences.flatMap(sentence => sentence.split(" "));

console.log(words); // Output: ["hello", "world", "javascript", "is", "fun"]

// another example with nested objects or array

© Hornbill Coding Society +91 9662332503 Hornbillcodingsociety.com 129


JavaSCRIPT

const customers = [

{ name: "Alice", orders: ["Apple", "Banana"] },

{ name: "Bob", orders: ["Mango"] },

];

// Without flat map

// Step 1: map() → extract the nested arrays

const mapped = customers.map(cust => cust.orders);

// Result: [["Apple", "Banana"], ["Mango"]]

const allOrders = mapped.flat(); // Flatten one level → ["Apple", "Banana", "Mango"]

// With flatMap

const allOrdersFlatMap = customers.flatMap(cust => cust.orders);

console.log(allOrders); // Output: ["Apple", "Banana", "Mango"]

30.9 SORT METHOD

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

fruits.sort( );

console.log(fruits); // Output: ['apple', 'banana', 'cherry'] Sort method works best with string and not number

const numbers = [100, 25, 300, 2];

numbers.sort( );

console.log(numbers); // Output: [100, 2, 25, 300] — not numerically correct!

// We have to sort number with compre function in Ascending order

numbers.sort((a, b) => a - b);

console.log(numbers); // Output: [2, 25, 100, 300]

// Descending order

numbers.sort((a, b) => b - a);

console.log(numbers); // Output: [300, 100, 25, 2]

130 Java Script +91 9662332503 Hornbillcodingsociety@gmail.com


JavaSCRIPT

30.10 ARRAY GROUPING

Introduced in ES2023

const grouped = Object.groupBy(array, callbackFn);

const people = [

{ name: "Alice", age: 21 },

{ name: "Bob", age: 25 },

{ name: "Charlie", age: 21 },

{ name: "David", age: 25 }

];

const grouped =Object.groupBy(people, person => person.age);

console.log(grouped);

/* { 21: [ { name: "Alice", age: 21 }, { name: "Charlie", age: 21 } ],

25: [ { name: "Bob", age: 25 }, { name: "David", age: 25 } ] } */

// Original

const movements = [200, -150, 450, -300, 1200, -50, 700, -100];

const groupedMovements = Object.groupBy(movements, movement =>

movement > 0 ? 'deposits' : 'withdrawals'

);

console.log("Grouped Movements:", groupedMovements);

/* Output: { deposits: [200, 450, 1200, 700], withdrawals: [-150, -300, -50, -100]} */

30.11 OTHER ARRAY METHODS

So far we created arrays with array literals i.e., by typing the content of the array or by using newArray()
constructor. However there are other ways of creating arrays as well i.e., we can create array programmatically

const arr1 = new Array(5)

console.log(arr1) // [empty x 7] it generates the empty array with 7 elememt

© Hornbill Coding Society +91 9662332503 Hornbillcodingsociety.com 131


JavaSCRIPT

we can’t use map method on the array created with above technique. To populate this array so we have some
special method to populate the array i.e., fill method()

• FILL METHOD () : is used to populat the elements of an array

Syntax : array.fill(value, start, end) value (required) – The value to fill the array with.
start (optional) – The index to start filling from (default is 0).
end (optional) – The index to stop filling (default is array.length). The end is not inclusive.

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

arr.fill(0, 1, 4);

console.log(x); // [1, 0, 0, 0, 5]

• ARRAY.FORM( ) : is used to populat the elements of an array

We can create an array from the scratch with the from method, However the difference is that we have to use
the Array object i.e., starting with capital A and assign it to the variable to store array in.

const arr1 = Array.from({length:10}, ()=>{2});

console.log(arr1); // [2,2,2,2,2,2,2,2,2,2 ]

const arr2 = Array.from({length: 5}, (cur, i)=>{i+1}); or Array.from({length: 5}, ( _ , i)=>{i+1});

console.log(arr2) // [1,2,3,4,5,6] here we are mapping the data with the index, However indexm is the second
parameter in the callback function after the array (as signature of callback is predefined) so we don’t need an first
parameter as we do not need an array so can use (underscore) _ also known as throwaway variable.

Note: The Array.from() method was introduced in JavaScript to create arrays from array-like or iterable
structures. Iterables include objects such as Strings, Maps, and Sets, which can be easily converted
into real arrays using Array.from(). This is also where the method gets its name—because it allows
us to create arrays from other types of iterable data.

30.12 NON DESTRUCTIVE METHOD OF ARRAY

reverse(), sort(), and splice(), all directly modify the underlying array. e.g., reverse() alters the original array
in place, which is generally discouraged if immutability is preferred. A better approach is to first create a
copy of the array using slice(), and then apply reverse() on that new array. This way, the original data remains
unchanged.

• TOREVERSED() : non destructive way to reverse the array. reverse mutate the original array. (ES2023)

132 Java Script +91 9662332503 Hornbillcodingsociety@gmail.com


JavaSCRIPT

const students = ["Anu", "Rahul", "Sneha", "Mohit"];

const reversedStudents = students.slice().reverse(); or we can eliminat these two steps and use

const reversedStudents = students.toReversed();

console.log("Reversed Array:", reversedStudents);

console.log("After Reverse (Original Still Intact):", students); // ["Anu", "Rahul", "Sneha", "Mohit"];

• TOSPLICED ( ) : non destructive way to splice an array .Spilice mutate the original array (ES2023).

we also have toSplice to use inplace of splice method

const colors = ["Red", "Green", "Blue", "Yellow"];

console.log("Original Array:", colors);

// Insert "Purple" at index 2 without removing anything

const newColors = colors.toSplice(2, 0, "Purple");

console.log("New Array (with Purple inserted):", newColors); // [ 'Red', 'Green', 'Purple', 'Blue', 'Yellow' ]

console.log("Original Array (unchanged):", colors); // [ 'Red', 'Green', 'Blue', 'Yellow' ]

• WITH( ) : non destructive way to replace the element of the array this method is again the substitute to the
splice ES2023

const students = ["Anu", "Rahul", "Sneha", "Mohit"];

const updatedStudents = students.with(2, "Divya"); // Replace "Sneha" (index 2) with "Divya"

console.log("Updated Students:", updatedStudents); // ["Anu", "Rahul", "Divya", "Mohit"]

console.log("Original Students:", students); // ["Anu", "Rahul", "Sneha", "Mohit"]

with(index, value) returns a new array with the value at index replaced. The original students array stays unchanged.

30.13 INTERVIEW QUESTIONS

• What is the difference between the forEach and map? ( almost asked in every interview)
• What is the difference between map, Filter and reduce ?
• What are the destructive and non destructive methods on the array
• What is MAP and flatMap method on the array ?
• What is the difference between some and every method ?

© Hornbill Coding Society +91 9662332503 Hornbillcodingsociety.com 133


YouTube

Adarsh colony, Gole ka Mandir, Morar,


Gwalior (Madhya Pradesh), 474005
YouTube

Adarsh colony, Gole ka Mandir, Morar,


Gwalior (Madhya Pradesh), 474005
YouTube

Adarsh colony, Gole ka Mandir, Morar,


Gwalior (Madhya Pradesh), 474005

You might also like