- Introduction
- Variables
- Hoisting
- Scope
- Coercion
- Logical Operator Return Values
- Equality Operators
- Nullish Coalescing Operator
- String Datatype & String Methods
- Functions
- Closure
- Arrays
- Array forEach Method
- Array map Method
- Array filter Method
- Array find Method
- Array some Method
- Object
- Object values Method
- Object keys Method
- Object entries Method
- Object freeze Method
- Object seal Method
- this Keyword
- A New Keyword
- Prototypes
- Class
- For...in Loop
- Try Catch Statement
- Try Catch Finally
- Understanding Promise
- Promise Then Method
- Promise Catch Method
- Why We Need Promise?
- Async / Await
- JavaScript DOM
- JavaScript is a cross-platform, object-oriented scripting language used to make webpages interactive
-
Netscape Communications hired Brendan Eich to develop Javascript
- Mocha [Initial release]
- LiveScript[Renamed]
- Javascript[Finally]
Feature | var |
let |
const |
---|---|---|---|
Scope | Function scope | Block scope | Block scope |
Hoisting | Hoisted to the top of the function or global scope; initialized with undefined |
Hoisted to the top of the block but not initialized; ReferenceError if accessed before declaration | Hoisted to the top of the block but not initialized; ReferenceError if accessed before declaration |
Re-declaration | Allowed within the same scope | Not allowed within the same block | Not allowed within the same block |
Re-assignment | Allowed | Allowed | Not allowed |
Block Scope Example | if (true) { var x = 1; } console.log(x); // Outputs 1 |
if (true) { let x = 1; } console.log(x); // ReferenceError |
if (true) { const x = 1; } console.log(x); // ReferenceError |
Global Object Property | Creates a property on the global object (e.g.,window in browsers) |
Does not create a property on the global object | Does not create a property on the global object |
- Example Usage
var name = 'Alice';
name = 'Bob';
console.log(name); // Outputs Bob
let age = 30;
age = 31;
console.log(age); // Outputs 31
const PI = 3.14;
PI = 3.1415; // Error: Assignment to constant variable
console.log(PI); // Outputs 3.14
- Hoisting in JavaScript is a behavior where variables and function declarations are moved ("hoisted") to the top of their containing scope before the code is executed.
- This means that we can use variables and functions before you declare them in the code.
- Variable and Function Hoisting are two different types of hoisting.
console.log(myVar); // Output: undefined
var myVar = 10;
greet(); // Output: "Hello, world!"
function greet() {
console.log("Hello, world!");
}
- Scope refers to the accessibility of variables, functions, and objects in certain parts of your code.
- It determines where values and expressions are visible or can be referenced.
- There are several types of scope in JavaScript:
- Global scope
- Local scope
- Block scope
- Function Scope vs. Block Scope (Interview questions)
- Lexical Scope (Static Scope)
- Global Object (Interview questions)
-
Table Comparison Scope Type Declaration Accessible Where Example Variable Declaration Notes Global Scope Variables declared outside any function or block Anywhere in the code, including inside functions var globalVar = "I'm global!";
Global variables are properties of the window
object in browsers.Local Scope Variables declared inside a function Only within the function where they are declared function myFunc() { var localVar = "I'm local!"; }
Local variables cannot be accessed outside the function. Block Scope Variables declared inside a block (e.g., if
,for
), usinglet
orconst
Only within the block where they are declared if (true) { let blockVar = "I'm block-scoped!"; }
Block-scoped variables are confined to the block they are declared in. Function Scope Variables declared using var
within a functionAccessible throughout the entire function function myFunc() { var funcScoped = "I'm function-scoped!"; }
var
is not block-scoped; it is function-scoped, available across the function.Lexical Scope Nested functions within other functions Inner functions can access variables from their outer functions function outerFunc() { var outerVar = "I'm outer!"; function innerFunc() { console.log(outerVar); } }
Lexical scope determines how variable names are resolved in nested functions. Global Object Variables declared in the global scope Anywhere in the code, globally as properties of the global object var globalVar = "Hello!"; console.log(window.globalVar);
In browsers, the global object is the window
object.
Type coercion in JavaScript is the automatic or implicit conversion of values from one data type to another (such as strings to numbers). JavaScript provides both implicit and explicit ways to perform type coercion.
Implicit coercion happens automatically when JavaScript tries to perform an operation on mismatched types.
When using the +
operator with a string, JavaScript converts the other operand to a string.
const result = "The number is " + 10;
console.log(result); // "The number is 10"
Number Coercion
- When using mathematical operators (other than +), JavaScript converts strings to numbers.
const result = "5" * "2";
console.log(result); // 10
Boolean Coercion
- Values in conditions are automatically coerced to booleans.
const value = "Hello";
if (value) {
console.log("This is true"); // "This is true"
}
- Explicit coercion is when you explicitly convert a value to another type using JavaScript functions or operators.
String()
- Converts a value to a string.
const num = 10;
const str = String(num);
console.log(str); // "10"
Number()
- Converts a value to a number.
const str = "123";
const num = Number(str);
console.log(num); // 123
Boolean()
- Converts a value to a boolean.
const str = "Hello";
const bool = Boolean(str);
console.log(bool); // true
parseInt()
- Parses a string and returns an integer.
const str = "10px";
const num = parseInt(str);
console.log(num); // 10
parseFloat()
- Parses a string and returns a floating-point number.
const str = "10.5px";
const num = parseFloat(str);
console.log(num); // 10.5
toString()
- Converts and returns a string representation of the value.
const num = 10;
const str = num.toString();
console.log(str); // "10"
(Unary Plus) Converts a value to a number.
const str = "123";
const num = +str;
console.log(num); // 123
!! (Double Negation)
- Converts a value to a boolean.
const value = "Hello";
const bool = !!value;
console.log(bool); // true
Logical operators in JavaScript, such as &&
, ||
, and !
, return the value of one of the operands in some cases, rather than a simple boolean.
const isAlienPresent = true;
const isSpaceshipFunctional = false;
// Using logical OR to determine if we can escape
const canEscape = isAlienPresent || isSpaceshipFunctional;
console.log(canEscape); // Output: true (We can escape because the alien might help us!)
JavaScript has two types of equality operators:
==
(Abstract Equality): Converts the operands to the same type before making the comparison.===
(Strict Equality): No type conversion is performed, and the operands must be of the same type to be considered equal.
const alienDNA = "Zorgon";
const humanDNA = "zorgon";
console.log(alienDNA == humanDNA); // Output: true (Abstract Equality performs type conversion)
console.log(alienDNA === humanDNA); // Output: false (Strict Equality does not convert types)
The nullish coalescing operator (??
) returns the right-hand operand when the left-hand operand is null
or undefined
, otherwise, it returns the left-hand operand.
const oxygenLevel = null;
const defaultOxygenLevel = 100;
const safeOxygenLevel = oxygenLevel ?? defaultOxygenLevel;
console.log(safeOxygenLevel); // Output: 100 (We're setting oxygen levels to safe defaults)
Strings in JavaScript are immutable and are used to store textual data. Common methods include .length
, .charAt()
, .substring()
, .toUpperCase()
, .toLowerCase()
, .split()
, .replace()
, etc.
const alienMessage = "Greetings from planet Zorgon";
// Translate the message to uppercase for human readability
console.log(alienMessage.toUpperCase()); // Output: "GREETINGS FROM PLANET ZORGON"
Functions in JavaScript are blocks of code designed to perform a particular task, defined using the function
keyword, or as arrow functions (=>
).
function decodeMessage(message) {
return message.split("").reverse().join("");
}
const alienMessage = "nozroG morf sgniteerG";
console.log(decodeMessage(alienMessage)); // Output: "Greetings from Zorgon"
A closure is a feature where an inner function has access to the outer (enclosing) function’s variables. The closure preserves the scope chain that existed when the function was created.
function createEnergyShield(level) {
return function () {
console.log(`Alien energy shield activated at level ${level}!`);
};
}
const activateShield = createEnergyShield(5);
activateShield(); // Output: "Alien energy shield activated at level 5!"
Arrays are list-like objects in JavaScript used to store multiple values. Arrays have various methods like .push()
, .pop()
, .shift()
, .unshift()
, etc.
const crew = ["Captain", "Engineer", "Navigator"];
// Add a new alien crew member
crew.push("Zorgon");
console.log(crew); // Output: ["Captain", "Engineer", "Navigator", "Zorgon"]
The forEach()
method executes a provided function once for each array element.
const crew = ["Captain", "Engineer", "Navigator", "Zorgon"];
crew.forEach((member) => {
console.log(`${member} has completed the safety check.`);
});
// Output:
// Captain has completed the safety check.
// Engineer has completed the safety check.
// Navigator has completed the safety check.
// Zorgon has completed the safety check.
Objects in JavaScript are collections of key-value pairs. Objects can be created using object literals or constructors.
const alienSpecies = {
name: "Zorgon",
planet: "Zorg",
strength: 100,
};
console.log(alienSpecies.name); // Output: "Zorgon"
The this
keyword in JavaScript refers to the object that is executing the current function.
const spaceship = {
name: "Galactic Cruiser",
startEngine: function () {
console.log(`${this.name} is starting its engine!`);
},
};
spaceship.startEngine(); // Output: "Galactic Cruiser is starting its engine!"
JavaScript classes are templates for creating objects, introduced in ES6, and are a special type of function.
class Alien {
constructor(name, planet) {
this.name = name;
this.planet = planet;
}
invade() {
console.log(`${this.name} from ${this.planet} is invading Earth!`);
}
}
const zorgon = new Alien("Zorgon", "Zorg");
zorgon.invade(); // Output: "Zorgon from Zorg is invading Earth!"
The try...catch
statement allows you to test a block of code for errors. If an error occurs, control is passed to the catch
block.
try {
throw new Error("Hyperdrive malfunction!");
} catch (error) {
console.log(`Alert: ${error.message}`); // Output: "Alert: Hyperdrive malfunction!"
}
The try...catch...finally
statement allows you to test for errors and also execute code regardless of the result, whether an error was caught or not.
try {
console.log("Starting preflight checks...");
throw new Error("Oxygen levels low!");
} catch (error) {
console.log(`Error: ${error.message}`);
} finally {
console.log("Preflight checks complete.");
}
// Output:
// Starting preflight checks...
// Error: Oxygen levels low!
// Preflight checks complete.
- A Promise contains both the producing code and calls to the consuming code
Promise.resolve(value)
Promise.reject(reason)
Promise.all(iterable)
Promise.race(iterable)
Promise.any(iterable)
Promise.allSettled(iterable)
Promise.prototype.then(onFulfilled, onRejected)
Promise.prototype.catch(onRejected)
Promise.prototype.finally(onFinally)
Returns a Promise
object that is resolved with the given value.
const promise = Promise.resolve(42);
promise.then((value) => {
console.log(value); // 42
});
Returns a Promise
object that is rejected with the given reason.
const promise = Promise.reject(new Error("Something went wrong!"));
promise.catch((error) => {
console.error(error); // Error: Something went wrong!
});
Returns a Promise
that resolves when all of the promises in the iterable have resolved or rejects if any promise rejects.
const promise1 = Promise.resolve(3);
const promise2 = 42;
const promise3 = new Promise((resolve, reject) => {
setTimeout(resolve, 100, "foo");
});
Promise.all([promise1, promise2, promise3]).then((values) => {
console.log(values); // [3, 42, 'foo']
});
Returns a Promise
that resolves or rejects as soon as one of the promises in the iterable resolves or rejects.
const promise1 = new Promise((resolve, reject) => {
setTimeout(resolve, 500, "one");
});
const promise2 = new Promise((resolve, reject) => {
setTimeout(resolve, 100, "two");
});
Promise.race([promise1, promise2]).then((value) => {
console.log(value); // "two" - because it was the fastest
});
Returns a Promise
that resolves as soon as any of the promises in the iterable resolves, or rejects if all of the promises reject.
const promise1 = Promise.reject(new Error("fail1"));
const promise2 = Promise.reject(new Error("fail2"));
const promise3 = Promise.resolve(42);
Promise.any([promise1, promise2, promise3])
.then((value) => {
console.log(value); // 42
})
.catch((error) => {
console.error(error); // AggregateError: All promises were rejected
});
Returns a Promise
that resolves after all of the given promises have either resolved or rejected, with an array of objects that each describe the outcome of each promise.
const promise1 = Promise.resolve(42);
const promise2 = Promise.reject(new Error("fail"));
const promise3 = new Promise((resolve, reject) => {
setTimeout(resolve, 100, "foo");
});
Promise.allSettled([promise1, promise2, promise3]).then((results) => {
console.log(results);
// [
// { status: 'fulfilled', value: 42 },
// { status: 'rejected', reason: Error: fail },
// { status: 'fulfilled', value: 'foo' }
// ]
});
Attaches callbacks for the resolution and/or rejection of the Promise.
const promise = new Promise((resolve, reject) => {
setTimeout(() => resolve("foo"), 300);
});
promise.then((value) => {
console.log(value); // "foo"
});
Attaches a callback for only the rejection of the Promise.
const promise = new Promise((resolve, reject) => {
reject(new Error("Oops!"));
});
promise.catch((error) => {
console.error(error); // Error: Oops!
});
Attaches a callback that is invoked when the Promise is settled (fulfilled or rejected), allowing you to run some code regardless of the outcome.
const promise = new Promise((resolve, reject) => {
resolve("done");
});
promise
.then((value) => {
console.log(value); // "done"
})
.finally(() => {
console.log("Promise has been settled.");
});
- Chaining Promises:
const promise = new Promise((resolve, reject) => {
resolve(1);
});
promise
.then((value) => {
console.log(value); // 1
return value + 1;
})
.then((value) => {
console.log(value); // 2
return value + 1;
})
.then((value) => {
console.log(value); // 3
});
- Handling Errors in Promises:
const promise = new Promise((resolve, reject) => {
reject(new Error("Failed"));
});
promise
.then((value) => {
console.log(value);
})
.catch((error) => {
console.error("Caught:", error.message); // "Caught: Failed"
});
- Using
async
/await
with Promises: [refer next topic - Interview Question]
function delay(ms) {
return new Promise((resolve) => setTimeout(resolve, ms));
}
async function asyncFunction() {
console.log("Start");
await delay(1000);
console.log("After 1 second");
}
asyncFunction();
- Executing Multiple Promises Sequentially:
function asyncTask(value, ms) {
return new Promise((resolve) => setTimeout(() => resolve(value), ms));
}
async function executeSequentially() {
const result1 = await asyncTask(1, 1000);
console.log(result1); // 1
const result2 = await asyncTask(2, 1000);
console.log(result2); // 2
const result3 = await asyncTask(3, 1000);
console.log(result3); // 3
}
executeSequentially();
- Promise Timeout Example:
function timeoutPromise(promise, ms) {
const timeout = new Promise((_, reject) =>
setTimeout(() => reject(new Error("Timeout")), ms)
);
return Promise.race([promise, timeout]);
}
const delayedPromise = new Promise((resolve) =>
setTimeout(() => resolve("Success"), 5000)
);
timeoutPromise(delayedPromise, 2000)
.then((value) => {
console.log(value);
})
.catch((error) => {
console.error(error.message); // "Timeout"
});
- Getting Element by Id
- Getting Element by Name
- Getting Elements by Class Name
- Getting Elements by Tag Name
- Getting Child Elements
- Getting Parent Element
- Create Element
- Remove Element
- Get Attribute of Element
- Create or Update Attribute
- Types of Event Handlers
- Handling Mouse Events
- Handling Keyboard Events
The getElementById()
method is used to access an HTML element by its unique id
attribute.
const element = document.getElementById("myElementId");
console.log(element);
This will retrieve the element with the id
of myElementId
and allow you to manipulate it.
The getElementsByName()
method returns a NodeList of all elements with a given name
attribute.
const elements = document.getElementsByName("myElementName");
elements.forEach((element) => console.log(element));
This retrieves all elements with the name
of myElementName
.
The getElementsByClassName()
method returns a collection of elements with a specified class name.
const elements = document.getElementsByClassName("myClassName");
Array.from(elements).forEach((element) => console.log(element));
This retrieves all elements with the class name myClassName
.
The getElementsByTagName()
method returns a live HTMLCollection of elements with a given tag name.
const elements = document.getElementsByTagName("div");
Array.from(elements).forEach((element) => console.log(element));
This retrieves all <div>
elements in the document.
The children
property returns a live HTMLCollection of the child elements of a specified element.
const parentElement = document.getElementById("parent");
const childElements = parentElement.children;
Array.from(childElements).forEach((child) => console.log(child));
This retrieves all child elements of the element with id
parent
.
The parentElement
property returns the parent element of a specified element.
const childElement = document.getElementById("child");
const parentElement = childElement.parentElement;
console.log(parentElement);
This retrieves the parent element of the element with id
child
.
The createElement()
method creates an HTML element specified by tag name.
const newElement = document.createElement("div");
newElement.textContent = "Hello, World!";
document.body.appendChild(newElement);
This creates a new <div>
element with the text "Hello, World!" and appends it to the body.
The remove()
method removes the specified element from the DOM.
const elementToRemove = document.getElementById("myElement");
elementToRemove.remove();
This removes the element with id
myElement
from the DOM.
The getAttribute()
method returns the value of a specified attribute on an element.
const element = document.getElementById("myElement");
const attributeValue = element.getAttribute("data-value");
console.log(attributeValue);
This retrieves the value of the data-value
attribute on the element with id
myElement
.
The setAttribute()
method adds a new attribute or changes the value of an existing attribute on an element.
const element = document.getElementById("myElement");
element.setAttribute("data-value", "newValue");
This sets the data-value
attribute to newValue
on the element with id
myElement
.
Event handlers can be added to HTML elements to respond to user interactions. There are three common ways to add event handlers:
-
Inline Event Handlers: Specified directly within the HTML element.
<button onclick="alert('Button Clicked!')">Click Me</button>
-
Property Event Handlers: Assigned as properties of DOM elements.
const button = document.getElementById("myButton"); button.onclick = () => alert("Button Clicked!");
-
Event Listener Method: Using
addEventListener()
to register an event handler.const button = document.getElementById("myButton"); button.addEventListener("click", () => alert("Button Clicked!"));
Mouse events are fired when the user interacts with the mouse, such as clicking or moving the cursor.
click
: Fired when the user clicks on an element.dblclick
: Fired when the user double-clicks on an element.mouseover
: Fired when the user moves the mouse over an element.mouseout
: Fired when the user moves the mouse out of an element.
const button = document.getElementById("myButton");
button.addEventListener("click", () => alert("Button Clicked!"));
Keyboard events are fired when the user interacts with the keyboard, such as pressing a key.
keydown
: Fired when a key is pressed.keyup
: Fired when a key is released.keypress
: Fired when a key that produces a character value is pressed down.
document.addEventListener("keydown", (event) => {
console.log(`Key pressed: ${event.key}`);
});
This logs the key that was pressed.