Learn JavaScript from Scratch: A Complete Guide


Understanding JavaScript: Basics and Beyond
JavaScript is a versatile scripting language that brings web pages to life with interactive features and dynamic behavior. It enables complex functionalities on web pages, making it an essential tool for modern web development. Here’s a comprehensive overview of JavaScript, covering its core concepts and advanced features.
Basic Information
What is JavaScript?
JavaScript is a scripting language that allows you to implement complex features on web pages. While HTML provides the structure and CSS the style, JavaScript adds interactivity and special effects.
Characteristics
Dynamic Behavior: JavaScript allows dynamic updates to web pages without needing to reload.
Validation: Commonly used for form validation on websites.
Ease of Use: Can be written in any text editor and executed directly in web browsers.
JavaScript Basics
Hoisting: JavaScript moves all declarations to the top of the current scope. This applies to variables and functions.
Strict Mode: Enforces a stricter set of rules for writing secure and cleaner code. It helps prevent common coding errors and unsafe actions.
'use strict' // js default behaviour
Variable Declarations:
var
: Function-scoped and can be hoisted.let
: Block-scoped and can be reassigned.const
: Block-scoped and cannot be reassigned.In JavaScript, if you declare a variable without assigning a value to it, the output will be
undefined
.
Comments in JavaScript
Comments are used to explain code and make it more readable. They are ignored during code execution and do not affect the program's behavior.
Single-line comments: Use
//
to add comments that span a single line.// This is a single-line comment
Multiline comments: Use
/* */
to add comments that span multiple lines./* * This is a multiline comment * It can span multiple lines */
Displaying Variable Values
To display the values of multiple variables at once, you can use console.table()
. This method provides a tabular representation of the data for better readability.
console.table([name, address, phone, email]);
By using console.table()
, you can visualize the values of all specified variables in a structured format.
Key JavaScript Concepts
JavaScript Engine: JavaScript code is executed by the browser's JavaScript engine, so functions like
alert()
run within the browser environment.Semicolons: While semicolons (
;
) are not strictly required in JavaScript, it is a good practice to use them to enhance code readability and avoid potential issues.Handling Undefined Values: If a variable does not display
undefined
, you can explicitly usenull
to represent a non-existent or invalid value.Symbols for Uniqueness: Symbols are often used for creating unique identifiers, especially in frameworks like React.js, to avoid naming collisions.
Type Checking:
console.log(typeof null)
outputs:object
console.log(typeof undefined)
outputs:undefined
Comparison and Equality:
===
checks both the value and its datatype, ensuring strict equality.
Language Inconsistencies: JavaScript has some inconsistencies in its design that can lead to unexpected behavior.
Code Readability: Focus on writing readable and maintainable code, which is crucial for effective programming.
Dynamic Typing: JavaScript is a dynamically-typed language, meaning variable types are determined at runtime.
Date Object: In JavaScript,
Date
is a built-in object used for handling dates and times.Global Object: Within the browser, the global object is the
window
object, which provides access to global properties and methods.The
this
Keyword: In JavaScript,this
refers to the context in which a function is executed, and it works primarily within objects rather than standalone functions.
Data Types
Primitive/in-built Types (immutable):
String
Number
BigInt (15520n)
Boolean
Undefined
Null (standalone value)
Symbol
Non-Primitive/derived/reference Types (mutable):
Every time give a new value
Object
Array
Function
Type Conversion
let score = "18abc";
let score = null;
let score = undefined;
console.log(typeof score); // string
let valueInNumber = Number(score) // convert string to number
console.log(typeof valueInNumber); // number
console.log(valueInNumber); // string-number -> number
console.log(valueInNumber); // string -> NaN
console.log(valueInNumber); // null -> 0
console.log(valueInNumber); // undefined -> NaN
console.log(valueInNumber); // boolean true:1 false:0
Memory Types in JavaScript
JavaScript uses two types of memory to manage data: Stack and Heap.
Stack Memory:
Used for primitive data types (e.g.,
number
,string
,boolean
).Variables hold actual values.
When you assign a primitive value to a variable, you get a copy of that value.
let x = 10; // Stack holds the value 10
let y = x; // y also holds the value 10
Heap Memory:
Used for non-primitive data types (e.g.,
object
,array
,function
).Variables hold references to the memory location where the data is stored.
When you assign a non-primitive value to a variable, you get a reference to the original value, not a copy.
let obj1 = { name: 'Alice' }; // Heap holds a reference to the object
let obj2 = obj1; // obj2 references the same object as obj1
Strings in JavaScript
String Concatenation
Instead of using the
+
operator to concatenate strings, you can use template literals, which are also known as string interpolation. This method provides a cleaner and more readable way to combine strings.
const v1 = 'Hello';
const v2 = 'World';
console.log(`${v1} is ${v2}`); // Output: Hello is World
Declaring Strings as Objects
You can declare a string as an object using the
String
constructor. This approach creates a string object rather than a primitive string value.
let name = new String("Mayur");
console.log(name[0]); // Output: M
console.log(name.__proto__); // Output: {}
Arrays
JavaScript provides several methods for manipulating arrays. Here’s a summary of some common operations:
Adding and Removing Elements:
push(element)
: Adds an element to the end of the array.pop()
: Removes the last element from the array.unshift(element)
: Adds an element to the front of the array.shift()
: Removes the first element from the array.
Handling Out-of-Bounds Indexes:
- When accessing an index outside the bounds of an array, JavaScript will return
-1
.
- When accessing an index outside the bounds of an array, JavaScript will return
Converting Arrays to Strings:
arr.join()
: Converts an array into a string. For example,[1, 2, 3].join()
results in"1,2,3"
.
Difference Between
slice
andsplice
:slice(start, end)
: Returns a new array containing the elements from the start index up to, but not including, the end index. It does not modify the original array.splice(start, deleteCount, item1, item2, ...)
: Modifies the original array by removing or replacing elements from the start index. It returns an array of the removed elements.
Combining and Flattening Arrays:
arr1.push(arr2)
: Addsarr2
as a single element toarr1
, resulting in an array of arrays.arr3 = arr1.concat(arr2)
: Mergesarr1
andarr2
into a new arrayarr3
.arr3 = [...arr1, ...arr2]
: Uses the spread operator to mergearr1
andarr2
into a new arrayarr3
.arr1.flat(Infinity)
: Flattens an array of arrays into a single array.
Creating Arrays:
Array.from("Mayur")
: Converts a string into an array of characters.Array.of(num1, num2, num3)
: Creates a new array with the specified numbers.
Objects
Object Declaration
Objects in JavaScript can be declared in two ways:
Literal Notation:
const student = { name: 'John', age: 25 };
Constructor Function:
function Student(name, age) { this.name = name; this.age = age; } const student = new Student('John', 25);
Singleton Pattern
When declaring an object using the literal notation, it does not create a singleton object. However, when using the constructor function, it can create a singleton object. Another way to create a singleton object is using Object.create()
.
Freezing Objects
You can prevent changes to an object by using Object.freeze()
. This method makes an object immutable, meaning you cannot change its values or keys after freezing.
Object.freeze(student);
this
Keyword
The this
keyword refers to the current context or the object to which the method belongs. It provides a reference to the same object.
Accessing Object Values
You can access object values in two ways:
Dot notation:
student.email;
Bracket notation:
student['email'];
Merging Objects
To merge two objects, you can use either Object.assign()
or the spread operator.
Using
Object.assign()
:const obj3 = Object.assign({}, obj1, obj2);
Using the spread operator:
const obj3 = { ...obj1, ...obj2 };
Getting Object Keys
To retrieve the keys of an object, use Object.keys()
:
Object.keys(obj1);
Object Destructuring
In modern JavaScript, you can destructure objects to extract values into variables:
const { name, age } = student;
Functions in JavaScript
In JavaScript, functions are fundamental building blocks. Here’s a breakdown of different types of functions and their characteristics:
Function Calls and Parameters
Arguments: Values passed to a function when calling it are called arguments.
Parameters: Variables listed as part of a function’s definition that receive the arguments are called parameters.
Return Statement: Code after the
return
statement in a function will not be executed.
Function Types
Declaration Function (Named Functions or Traditional Functions)
function helloWorld() { console.log('Hello World!'); } helloWorld; // This line references the function but does not call it
Function Call: Can be called before or after the function declaration.
Hoisting: Supported.
Expression Function (Anonymous Functions or Lambda Functions)
let helloWorld = function () { console.log('Hello World!'); }
Function Call: Can be called only after the function declaration.
Anonymous: Can be anonymous.
Hoisting: Not supported.
Arrow Function
let helloWorld = () => { console.log('Hello World!'); } let helloWorld = () => { return 'Hello World!'; }
Implicit Return: No need to use
return
if you use{}
.Explicit Return: Use
return
if you use{}
.Fat Arrow: An updated version of function expressions.
Function Call: Can be called only after the function declaration.
Hoisting: Not supported.
IIFE (Immediately Invoked Function Expressions)
(function chai() { // Named IIFE console.log(`DB CONNECTED`); })(); // If you use a named function, it's called a named IIFE
Syntax:
()();
where the first()
defines the function and the second()
executes it.Global Scope: Helps avoid pollution of the global scope by encapsulating variables.
End with
;
: Essential to terminate the expression properly.
Advanced Topics
JavaScript Execution Context
JavaScript code execution occurs in two phases:
Memory Creation Phase: Memory is allocated for variables and functions.
Execution Phase: The actual execution of the code happens during this phase.
In the browser environment, the value of this
refers to the window
object.
JavaScript operates as a single-threaded process.
Types of Execution Contexts
Global Execution Context
Function Execution Context
Eval Execution Context (related to hosting)
Control Flow in JavaScript
Conditional Statements
if
: Executes a block of code if a specified condition is true.if (condition) { // Code to execute if condition is true }
if - else
: Executes one block of code if a condition is true and another block if it is false.if (condition) { // Code to execute if condition is true } else { // Code to execute if condition is false }
if - else if - else
: Allows you to test multiple conditions.if (condition1) { // Code to execute if condition1 is true } else if (condition2) { // Code to execute if condition2 is true } else { // Code to execute if none of the above conditions are true }
switch
: Evaluates an expression and executes code blocks based on matching cases.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 no cases match }
Falsie Values
In JavaScript, the following values are considered falsie:
false
0
-0
BigInt 0n
""
(empty string)null
undefined
NaN
Truthy Values
The following values are considered truthy:
"0"
'false'
" "
(space)[]
(empty array){}
(empty object)function(){}
(empty function)
Nullish Coalescing Operator (??
)
The nullish coalescing operator returns the right-hand operand when the left-hand operand is null
or undefined
.
let val1;
val1 = 5 ?? 10; // val1 is 5
val1 = null ?? 10; // val1 is 10
val1 = undefined ?? 15; // val1 is 15
val1 = null ?? 10 ?? 20; // val1 is 10
console.log(val1);
Ternary Operator
The ternary operator is a shorthand for the if - else
statement.
// condition ? true : false
const iceTeaPrice = 100;
iceTeaPrice <= 80 ? console.log("less than 80") : console.log("more than 80");
Loops
Types:
for
,for-of
,for-in
,forEach()
Array Methods:
filter()
,map()
,reduce()
JavaScript provides various methods to iterate over data structures and perform operations. Here's an overview of some key looping mechanisms:
for...of
loop: Iterates over the values of iterable objects such as arrays, strings, maps, sets, and NodeLists.for (const item of iterable) { // code to execute }
for...in
loop: Iterates over the enumerable properties of an object.for (const key in object) { // code to execute }
forEach()
method: TheforEach()
method of Array instances executes a provided function once for each array element. It is a higher-order function and does not return any value; it returnsundefined
.array.forEach(element => { // code to execute });
filter()
method: Creates a new array with all elements that pass the test implemented by the provided function.const filteredArray = array.filter(element => condition);
map()
method: Creates a new array with the results of calling a provided function on every element in the calling array. This is used for operations.const mappedArray = array.map(element => operation);
reduce()
method: Executes a reducer function (that you provide) on each element of the array, resulting in a single output value.const result = array.reduce((accumulator, currentValue) => { // code to execute }, initialValue);
Map
object: AMap
is a collection of unique values and does not allow duplicates. It is not iterable.const map = new Map();
Callback Function
A callback function is a function that is passed as an argument to another function and is executed after some operation has been completed. It does not have a name and is often used to handle asynchronous operations or to provide custom behavior.
function someFunction(callback) {
// code
callback();
}
Document Object Model (DOM)
The DOM (Document Object Model) represents the structure of an HTML document as a hierarchical tree of objects. Here's a brief overview:
window
: The global object in JavaScript. It represents the window in which the script is running.- Hierarchy:
window --> document --> html
- Hierarchy:
Properties and Methods
innerText
: Does not display elements withdisplay: none
. It only shows text content visible on the page.innerHTML
: Displays elements withdisplay: none
. It shows all HTML content inside an element, regardless of its visibility.
Collections
NodeList
: Not an array, so methods likemap
are not available. Instead, useforEach
to iterate through aNodeList
.HTMLCollection
: Can be converted into an array usingArray.from(variableName)
for array methods.
Event Execution
In JavaScript, all events run sequentially. JavaScript is a sequentially executed language, meaning that code runs line by line in the order it is written.
Events in JavaScript
Events are a key part of web development, allowing you to create interactive and dynamic web applications. Here’s a guide on handling events in JavaScript:
Adding Event Listeners
Use
addEventListener
to handle events because it provides event propagation capabilities and can listen to more types of events.Event Types
Browser Events: Events related to user interactions with the browser.
Environment Events: Events related to changes in the environment or application state.
Event Propagation
Event propagation has two contexts:
Event Bubbling: Events propagate from the target element up to the root (bottom to top). This is the default behavior (
false
).Event Capturing: Events propagate from the root down to the target element (top to bottom). Set
true
to use event capturing.
Stopping Propagation
To prevent an event from propagating further, use
e.stopPropagation()
within the event listener.Preventing Default Behavior
To prevent the default behavior of a specified event from occurring, use
e.preventDefault()
.
Asynchronous JavaScript
JavaScript is traditionally a synchronous language, executing code line by line. However, it can handle asynchronous operations due to mechanisms such as APIs, setTimeout
, setInterval
, and more.
Synchronous vs Asynchronous:
JavaScript executes code synchronously, meaning one operation follows another in a sequential manner.
JavaScript also supports asynchronous operations through Web APIs, allowing tasks to be performed in the background, enabling non-blocking behavior.
Single Thread Process:
- JavaScript operates on a single-threaded model, meaning it processes one operation at a time.
Blocking Code:
Blocking code halts the execution flow until the operation is completed.
Example:
fs.readFileSync()
(synchronous file reading).
Non-Blocking Code:
Non-blocking code does not stop the execution flow, allowing other operations to continue while waiting for the asynchronous operation to complete.
Example:
fs.readFile()
(asynchronous file reading).
Web API / Node:
Web APIs are built into the browser and handle asynchronous tasks.
setTimeout()
andsetInterval()
are part of this API, used to schedule code execution.
Handlers and Callbacks:
A handler is a callback function provided to asynchronous methods like
setTimeout()
. It is referenced by passing the function name, not its execution.In
clearTimeout()
, the first parameter is the reference to thesetTimeout()
call.
Arguments in
setInterval()
:setInterval()
can take additional arguments after the interval time, which are passed to the callback function.
Example:
setTimeout(function() {
console.log('This is an asynchronous message.');
}, 1000); // 1 second delay
setInterval(function(arg) {
console.log('Interval message:', arg);
}, 1000, 'Hello'); // 1 second interval with argument
API
An API (Application Programming Interface) is a communication system between two languages or systems.
For example, to get information about a GitHub user, you can use the following URL:
api.github.com/users/mayurrogheliya
Before APIs became common, programmers used
XMLHttpRequest
, which is related to Ajax (Asynchronous JavaScript and XML).Whenever a response is received from a URL, it is most often in the form of a string. To convert this string into an object, you can use
JSON.parse()
.Additionally,
console.log
is a debugging tool provided by the JavaScript runtime. It is used to print information to the console for developers to inspect and debug their code.
Promises in JavaScript
A Promise is an object in JavaScript that represents the eventual completion or failure of an asynchronous operation.
Creating and Consuming Promises
First, create a Promise and then consume it.
let myPromise = new Promise((resolve, reject) => { // Asynchronous operation });
Handling Promise Resolution
resolve
: Used to handle successful completion of the Promise. Chained with.then()
.myPromise.then((result) => { // Handle success });
reject
: Used to handle failures of the Promise. Chained with.catch()
.myPromise.catch((error) => { // Handle error });
Fetch in JavaScript
The fetch()
method is a global function used to make network-based requests.
Error Handling: An error is only rejected if the request cannot be made. For instance, network issues or connectivity problems might cause a rejection.
HTTP errors, such as 404 (Not Found), do not cause the promise to be rejected. Instead, they resolve the promise with an
ok
property set tofalse
.Data Handling:
onfulfilled[]
: This handles the data when the promise is resolved.onrejection[]
: This handles the error when the promise is rejected.
Environment:
- In both web browsers and Node.js, the
fetch()
method is used for network requests and returns a promise that can be resolved or rejected based on the request's success or failure.
- In both web browsers and Node.js, the
Object-Oriented Programming (OOP) in JavaScript
JavaScript does have classes, but technically it does not have traditional classes as seen in some other languages. Therefore, it is not considered a fully object-oriented language.
JavaScript is primarily a prototype-based language.
Object-Oriented Programming (OOP) is a programming paradigm that focuses on the style and structure of code.
Object Literal
In JavaScript, an object literal is a straightforward way to define objects.
const date = new Date();
new
is a constructor function that builds or creates multiple instances from the same object.return this
indicates that the object itself is being returned, allowing the current context to be passed on.In the example above,
new Date()
creates a new instance of theDate
object.
The new
Keyword in JavaScript
The new
keyword is used to create a new instance of an object. Here's a breakdown of how it works:
Object Creation: The
new
keyword first creates a new, empty object, referred to as an instance.Constructor Function Call: The constructor function is called as a result of using the
new
keyword. It packs the arguments and provides them to the constructor function.Argument Injection: The arguments are injected into the
this
keyword, making them available within the constructor function.New Instance: Each time the constructor function is called with the
new
keyword, it returns a new instance of the object.
Prototype in JavaScript
JavaScript's default behavior is prototype-based. This allows for the following:
new
Keyword: Used to create instances of objects.this
Keyword: Refers to the context in which a function is called.Class: A syntactic sugar over JavaScript's prototype-based inheritance.
Prototype Chain
Array → Object → null
String → Object → null
Function → Object → null
In JavaScript, all prototypes are objects, and the object of a prototype is null
.
Every entity in JavaScript is an object, and the properties of the object are also available on these entities.
JavaScript provides constructors using the new
keyword.
Class Constructor in JavaScript
Class Keyword:
class
is a keyword used to define a class.Constructor: When creating an object using the
new
keyword, the constructor of the class is called. The constructor initializes the object.class MyClass { constructor() { // Initialization code here } } const myObject = new MyClass(); // Constructor is called here
instanceof
: Theinstanceof
operator checks if an object is an instance of a particular class.myObject instanceof MyClass; // Returns true if myObject is an instance of MyClass
Static Methods: Static methods belong to the class itself, not to instances of the class. They cannot be accessed from an instance of the class or used to create instances.
class MyClass { static myStaticMethod() { // Static method code here } } MyClass.myStaticMethod(); // Accessed directly from the class, not from an instance
Getters and Setters in JavaScript
Getter: Retrieves the value of a property. It is defined using the
get
keyword.get propertyName() { // code to get the value }
Setter: Sets the value of a property. It is defined using the
set
keyword.set propertyName(value) { // code to set the value }
Closure and Lexical Scope
Lexical Scope: In JavaScript, lexical scope means that functions have access to variables defined in their outer (enclosing) scopes. For example, an inner function can access variables from its outer function, but the outer function cannot access variables from its inner function. This is akin to a child getting ice-cream from the parent, but the parent not getting ice-cream from the child.
Closure: A closure occurs when a function retains access to its lexical scope even after the function has finished executing. This means that not only the function is returned, but the entire lexical scope is returned as well.
Event Handlers: The
onclick
event requires a function to be assigned to it.
// Example of a closure
function outerFunction() {
let outerVariable = 'I am outside!';
function innerFunction() {
console.log(outerVariable); // Accesses outerVariable
}
return innerFunction; // Returns the inner function
}
const myFunction = outerFunction(); // myFunction is now a closure
myFunction(); // Logs: 'I am outside!'
Conclusion
JavaScript is a powerful language that has evolved significantly, allowing developers to create rich and interactive web applications. From its basics like variables, functions, and loops to advanced concepts like asynchronous programming and the DOM, mastering JavaScript is essential for modern web development. By understanding its core principles and leveraging its capabilities, you can build efficient, maintainable, and scalable web applications.
Subscribe to my newsletter
Read articles from Mayur Rogheliya directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by

Mayur Rogheliya
Mayur Rogheliya
I am passionate about learning, sharing knowledge, and growing through meaningful connections. My journey is all about embracing new challenges, evolving with every step, and collaborating with others to build something impactful.