Core mechanics and high-level concepts of the modern web language.
let / const (Block scope)===)map, filter, reducethis contextJavaScript (JS) is a lightweight, interpreted, or just-in-time compiled programming language with first-class functions. While it is most well-known as the scripting language for Web pages, many non-browser environments also use it, such as Node.js, Apache CouchDB and Adobe Acrobat.
Modern JavaScript uses let and const for variable declaration, replacing the legacy
var.
let score = 10;
const API_URL = "https://api.viva.com";
JavaScript defines 8 built-in types, categorized into Primitives and Objects.
| Type | Description |
|---|---|
| Number | Double-precision 64-bit binary format IEEE 754. |
| String | Immutable sequence of UTF-16 code units. |
| Boolean | Logical entity: true or false. |
| BigInt | Represent integers with arbitrary precision. |
Arithmetic operators are used to perform mathematical operations in JavaScript. Here are some common ones:
Addition (+): Adds two numbers.
let sum = 5 + 3; // sum is 8
Subtraction (-): Subtracts one number from another.
let difference = 10 - 3; // difference is 7
Multiplication (*): Multiplies two numbers.
let product = 4 * 6; // product is 24
Division (/): Divides one number by another.
let quotient = 15 / 3; // quotient is 5
Modulus (%): Returns the remainder of a division.
let remainder = 10 % 3; // remainder is 1
Relational operators are used to compare values. They return a Boolean result (true or false).
Equality (==): Checks if two values are equal, but it may perform type coercion.
5 == "5"; // true (value comparison, type coerced)
Inequality (!=): Checks if two values are not equal, but it may perform type coercion.
5 != "6"; // true (value comparison, type coerced)
Strict Equality (===): Checks if two values are equal without type coercion (same value and same type).
5 === "5"; // false (strict equality)
Strict Inequality (!==): Checks if two values are not equal without type coercion.
5 !== "5"; // true (strict inequality)
Logical operators are used to perform logical operations.
AND (&&): Returns true if both operands are true.
true && true; // true
true && false; // false
OR (||): Returns true if at least one operand is true.
true || false; // true
false || false; // false
NOT (!): Negates the value of an operand.
!true; // false
!false; // true
Bitwise operators perform operations on binary representations of numbers.
Bitwise AND (&): Performs a bitwise AND operation.
5 & 3; // 1
Bitwise OR (|): Performs a bitwise OR operation.
5 | 3; // 7
Bitwise XOR (^): Performs a bitwise XOR (exclusive OR) operation.
5 ^ 3; // 6
Increment and decrement operators are used to increase or decrease the value of a variable.
Increment (++): Increases the value of a variable by 1.
let x = 5;
x++; // x is now 6
Decrement (--): Decreases the value of a variable by 1.
let y = 10;
y--; // y is now 9
Assignment operators are used to assign values to variables.
Assignment (=): Assigns a value to a variable.
let z = 15;
*Other Assignment Operators (e.g., +=, -=, =, /=): Perform an operation and assign the result to a variable in a single step.
let a = 5;
a += 3; // Equivalent to: a = a + 3; (a is now 8)
The ternary operator is a shorthand for an if-else statement. It returns one of two values based on a condition.
let age = 18;
let canVote = age >= 18 ? "Yes" : "No";
console.log(canVote); // "Yes"
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.
let value = null;
let defaultValue = "Default Value";
let result = value ?? defaultValue;
console.log(result); // "Default Value"
if StatementThe if statement is used for conditional execution of code. It evaluates a condition and
executes a block of code if the condition is true.
Syntax:
if (condition) {
// Code to execute if the condition is true
}
Example:
let age = 20;
if (age >= 18) {
console.log("You are an adult.");
}
if-else StatementThe if-else statement allows you to execute one block of code if a condition is true and another
block of code if the condition is false.
Syntax:
if (condition) {
// Code to execute if the condition is true
} else {
// Code to execute if the condition is false
}
Example:
let isRaining = true;
if (isRaining) {
console.log("Bring an umbrella.");
} else {
console.log("No need for an umbrella.");
}
if-else StatementYou can nest if-else statements inside each other to handle more complex conditions.
Syntax:
if (condition1) {
// Code to execute if condition1 is true
if (condition2) {
// Code to execute if condition2 is true
} else {
// Code to execute if condition2 is false
}
} else {
// Code to execute if condition1 is false
}
Example:
let score = 75;
if (score >= 60) {
console.log("You passed.");
if (score >= 90) {
console.log("You got an A grade!");
} else {
console.log("You got a B grade.");
}
} else {
console.log("You failed.");
}
if-else StatementA cascaded if-else statement is used when you have multiple conditions to check one after the
other.
Syntax:
if (condition1) {
// Code to execute if condition1 is true
} else if (condition2) {
// Code to execute if condition2 is true
} else if (condition3) {
// Code to execute if condition3 is true
} else {
// Code to execute if none of the conditions are true
}
Example:
let grade = 'B';
if (grade === 'A') {
console.log("Excellent!");
} else if (grade === 'B') {
console.log("Good job!");
} else if (grade === 'C') {
console.log("You can do better.");
} else {
console.log("Needs improvement.");
}
switch-case StatementThe switch-case statement is used to select one of many code blocks to be executed.
Syntax:
switch (expression) {
case value1:
// Code to execute if expression === value1
break;
case value2:
// Code to execute if expression === value2
break;
// More cases...
default:
// Code to execute if none of the cases match
}
Example:
let dayOfWeek = 'Monday';
switch (dayOfWeek) {
case 'Monday':
console.log("It's the start of the week.");
break;
case 'Friday':
console.log("Weekend is almost here!");
break;
default:
console.log("It's a weekday.");
}
break StatementThe break statement is used to exit a loop prematurely when a certain condition is met. It is
commonly used to terminate a loop early, preventing further iterations.
Example: Using break in a for loop
for (let i = 1; i <= 10; i++) {
if (i === 5) {
break; // Exit the loop when i equals 5
}
console.log(i);
}
In this example, the loop runs from 1 to 10, but when i becomes equal to 5, the
break statement is executed, and the loop terminates. So, only the numbers 1 through 4 are
printed.
continue StatementThe continue statement is used to skip the current iteration of a loop and proceed to the next
iteration. It allows you to skip over specific values or conditions without terminating the loop entirely.
Example: Using continue in a for loop
for (let i = 1; i <= 5; i++) {
if (i === 3) {
continue; // Skip iteration when i equals 3
}
console.log(i);
}
In this example, when i is equal to 3, the continue statement is executed, and the
loop proceeds to the next iteration. As a result, the number 3 is skipped in the output, and the loop
continues to print 1, 2, 4, and 5.
Math.abs(x)Description: Returns the absolute (positive) value of a number.
Example:
let num = -5;
let absoluteValue = Math.abs(num); // absoluteValue is 5
Math.round(x)Description: Rounds a number to the nearest integer.
Example:
let num = 5.49;
let rounded = Math.round(num); // rounded is 5
Math.ceil(x)Description: Rounds a number up to the nearest integer.
Example:
let num = 5.01;
let roundedUp = Math.ceil(num); // roundedUp is 6
Math.floor(x)Description: Rounds a number down to the nearest integer.
Example:
let num = 5.99;
let roundedDown = Math.floor(num); // roundedDown is 5
Math.random()Description: Generates a random decimal number between 0 (inclusive) and 1 (exclusive).
Example:
let randomNumber = Math.random(); // Generates a random number between 0 and 1 (e.g., 0.123456)
Math.max(x, y, z, ...)Description: Returns the largest of zero or more numbers.
Example:
let maxNumber = Math.max(10, 5, 20, 8); // maxNumber is 20
Math.min(x, y, z, ...)Description: Returns the smallest of zero or more numbers.
Example:
let minNumber = Math.min(10, 5, 20, 8); // minNumber is 5
Math.pow(x, y)Description: Returns the value of x to the power of y.
Example:
let result = Math.pow(2, 3); // result is 8 (2^3 = 8)
Math.sqrt(x)Description: Returns the square root of a number.
Example:
let squareRoot = Math.sqrt(25); // squareRoot is 5 (√25 = 5)
Math.PIDescription: A predefined constant representing the mathematical constant π (pi).
Example:
let circleArea = Math.PI * Math.pow(5, 2); // Calculates the area of a circle with radius 5
Math.trunc(x)Description: Returns the integer part of a number by removing the fractional part, effectively truncating the decimal portion.
Example:
let num = 5.78;
let truncated = Math.trunc(num); // truncated is 5
Arrays in JavaScript are ordered, integer-indexed collections. They are technically objects under the hood, but optimized for sequential access.
.map(): Transform each element. Returns new array..filter(): Keep elements that match condition. Returns new array..reduce(): Accumulate array into a single value..find(): Returns first element matching condition.Syntax of Creating an Array:
let fruits = ["apple", "banana", "cherry"];
Accessing Elements: You can access elements in an array using square brackets and the index of the element.
console.log(fruits[0]); // "apple"
console.log(fruits[1]); // "banana"
Length Attribute:
The length property of an array returns the number of elements in the array.
console.log(fruits.length); // 3
display the array elements:
let arr = [1,2,3,4,5,6]
for(i=0;i<arr.length;i++){
console.log(arr[i]);
}
find out all the even numbers from an array:
let arr = [1,2,3,4,5,6]
for(i=0;i<arr.length;i++){
if(arr[i]%2===0)
console.log(arr[i]);
}
Add 3 to each element in an array:
let arr = [1,2,3,4,5,6]
for(i=0;i<arr.length;i++){
arr[i]=arr[i]+3;
console.log(arr[i]);
}
Find out the maximum element in an array:
let arr = [4,5,8,2,7,1]
let max=arr[0];
for(i=0;i<arr.length;i++){
if(arr[i]>max){
max=arr[i];
}
}
console.log(max);
Sort the numbers in an array:
let arr = [4,5,8,2,7,1];
let c=0;
for(i=0;i<arr.length;i++){
for(j=i+1;j<arr.length;j++){
if(arr[i]>arr[j]){
c=arr[i];
arr[i]=arr[j];
arr[j]=c;
}
}
console.log(arr[i]);
}
Reverse the numbers in an array:
let arr = [1,2,3,4,5]
let s=0;
let e=arr.length-1;
while(s<e){
let temp = arr[s];
arr[s]=arr[e];
arr[e]=temp;
s++;
e--;
}
console.log(arr);
Multidimensional Array: JavaScript arrays can also hold other arrays, creating multidimensional arrays.
let matrix = [[1, 2, 3], [4, 5, 6], [7, 8, 9]];
console.log(matrix[1][2]); // Accesses the element 6
To create a multidimensional array, you can nest arrays within arrays. Here's an example of a 2D array (a grid with rows and columns):
let matrix = [
[1, 2, 3],
[4, 5, 6],
[7, 8, 9]
];
In this example, matrix is a 2D array with three rows and three columns.
You can access elements in a multidimensional array using multiple pairs of square brackets. The first pair selects the row, and the second pair selects the column:
console.log(matrix[0][0]); // Accesses the element in the first row and first column (1)
console.log(matrix[1][2]); // Accesses the element in the second row and third column (6)
You can use nested loops to iterate through the elements of a multidimensional array. For example, to print
all elements in the matrix:
for (let i = 0; i < matrix.length; i++) {
for (let j = 0; j < matrix[i].length; j++) {
console.log(matrix[i][j]);
}
}
This nested loop structure traverses each row and column, printing all the elements.
Multidimensional arrays are useful in various scenarios, including:
Matrices: Representing mathematical matrices for operations like matrix multiplication.
Grids: Storing data in a grid format, such as game boards, spreadsheets, or images (pixels).
Tabular Data: Storing tabular data with rows and columns, like a database table.
Nested Structures: Creating hierarchical or nested data structures.
Here are some more examples:
let ticTacToeBoard = [
['X', 'O', 'X'],
['O', 'X', 'O'],
['X', 'O', 'X']
];
let studentGrades = [
['Alice', 95, 88, 92],
['Bob', 89, 91, 87],
['Carol', 92, 87, 95]
];
let imagePixels = [
['#FF0000', '#00FF00', '#0000FF'],
['#000000', '#FFFFFF', '#808080'],
['#FFFF00', '#FF00FF', '#00FFFF']
];
let monthlyCalendar = [
['Jan', 'Feb', 'Mar'],
['Apr', 'May', 'Jun'],
['Jul', 'Aug', 'Sep'],
['Oct', 'Nov', 'Dec']
];
let firstColumn = [];
for (let i = 0; i < matrix.length; i++) {
firstColumn.push(matrix[i][0]);
}
console.log(firstColumn)
let matrix = [
[1, 2, 3],
[4, 5, 6],
[7, 8, 9]
];
let transpose = []
for (let i = 0; i < matrix.length; i++) {
transpose[i] = []
console.log(transpose)
for (let j = 0; j < matrix[i].length; j++) {
transpose[i][j] = matrix[j][i];
}
}
console.log(transpose)
output
[ [ 1, 4, 7 ], [ 2, 5, 8 ], [ 3, 6, 9 ] ]
let sum = 0
for (let i = 0; i < matrix.length; i++) {
for (let j = 0; j < matrix[i].length; j++){
sum=sum+matrix[i][j]
}
}
console.log(sum)
let max=matrix[0][0]
for (let i = 0; i < matrix.length; i++) {
for (let j = 0; j < matrix[i].length; j++) {
if(matrix[i][j]>max)
max=matrix[i][j];
}
}
console.log(max)
You have two matrices, matrixA and matrixB:
Matrix A:
1 2
3 4
Matrix B:
5 6
7 8
The goal is to find the product of these two matrices, which will result in a new matrix:
Product Matrix (Result):
19 22
43 50
Matrix multiplication involves multiplying each element of a row in the first matrix by each element in a corresponding column of the second matrix and summing these products. Here's a step-by-step explanation:
To calculate the element in the first row and first column of the product matrix (result[0][0]), you take the dot product of the first row of matrixA and the first column of matrixB:
To calculate result[0][1], you continue with the first row of matrixA but use the second column of matrixB:
Next, you move to the second row of the product matrix:
JavaScript provides various methods to manipulate arrays effectively. Here are some commonly used array methods:
map(callback): Creates a new array by applying a callback function to each
element of the original array.
let numbers = [1, 2, 3];
let doubled = numbers.map(x => x * 2); // [2, 4, 6]
filter(callback): Creates a new array with elements that satisfy a
condition defined in the callback function.
let scores = [85, 92, 78, 90, 88];
let highScores = scores.filter(score => score >= 90); // [92, 90]
reduce(callback): Applies a callback function to reduce an array to a
single value (e.g., summing all elements).
let numbers = [1, 2, 3, 4, 5];
let sum = numbers.reduce((acc, current) => acc + current, 0); // 15
indexOf(element): Returns the first index at which a specified element is
found in the array. Returns -1 if the element is not found.
let fruits = ["apple", "banana", "cherry"];
let index = fruits.indexOf("banana"); // 1
push(element): Adds an element to the end of the array and returns the new
length of the array.
let fruits = ["apple", "banana"];
let newLength = fruits.push("cherry"); // 3
pop(): Removes the last element from the array and returns that element.
let fruits = ["apple", "banana", "cherry"];
let removed = fruits.pop(); // "cherry"
shift(): Removes the first element from the array and returns that element.
let fruits = ["apple", "banana", "cherry"];
let removed = fruits.shift(); // "apple"
unshift(element): Adds one or more elements to the beginning of the array
and returns the new length.
let fruits = ["banana", "cherry"];
let newLength = fruits.unshift("apple"); // 3
slice(start, end): Returns a new array containing elements from the
original array within the specified range (from start to end, not inclusive).
let numbers = [1, 2, 3, 4, 5];
let sliced = numbers.slice(1, 4); // [2, 3, 4]
some(callback): Checks if at least one element in the array satisfies the
condition specified in the callback function. Returns true if any element meets the
condition; otherwise, false.
let numbers = [1, 3, 5, 7, 9];
let hasEven = numbers.some(x => x % 2 === 0); // false
every(callback): Checks if all elements in the array satisfy the condition
specified in the callback function. Returns true if all elements meet the condition;
otherwise, false.
let numbers = [2, 4, 6, 8, 10];
let allEven = numbers.every(x => x % 2 === 0); // true
concat(array): Combines the current array with another array(s) and returns
a new concatenated array.
let fruits1 = ["apple", "banana"];
let fruits2 = ["cherry", "orange"];
let combined = fruits1.concat(fruits2); // ["apple", "banana", "cherry", "orange"]
splice(start, deleteCount, item1, item2, ...): Changes the contents of an
array by removing or replacing existing elements and/or adding new elements.
let fruits = ["apple", "banana", "cherry"];
fruits.splice(1, 1, "orange", "grape"); // Removes "banana" and adds "orange" and "grape"
reverse(): Reverses the order of elements in the array.
let numbers = [1, 2, 3, 4, 5];
numbers.reverse(); // [5, 4, 3, 2, 1]
includes(): determines whether an array includes a certain value among its
entries, returning true or false as appropriate.
const array1 = [1, 2, 3];
console.log(array1.includes(2));
const pets = ['cat', 'dog', 'bat'];
console.log(pets.includes('cat'));
console.log(pets.includes('at'));
Syntax:
let singleQuotes = 'This is a string.';
let doubleQuotes = "This is another string.";
let backticks = `And this is a string using backticks.`;
length attribute of a string returns the number of characters in the string.Example:
let message = "Hello, world!";
let length = message.length; // length is 13
find out all the characters in a string :
var str = "Hello";
for (var i = 0; i < str.length; i++) {
console.log(str[i]);
}
reverse a string :
var str = "Hello";
let rev="";
for (var i = str.length-1; i >=0; i--) {
rev+=str[i];
}
console.log(rev);
retrive a string from a given string :
var str = "The quick brown fox jumps over the lazy dog";
var result = "";
var startIndex = str.indexOf("fox");
console.log(startIndex)
if (startIndex !== -1) {
var endIndex = startIndex + 3;
for (var i = startIndex; i < endIndex; i++) {
result += str[i];
}
}
console.log(result);
Because strings must be written within quotes, JavaScript will misunderstand this string:
let text = "We are the so-called "Vikings" from the north.";
console.log(text);
let text = "We are the so-called \"Vikings\" from the north.";
slice() method extracts a section of a string and returns it as a new string.start (inclusive) and end (exclusive) positions.Example:
let str = "JavaScript is fun!";
let sliced = str.slice(0, 10); // sliced is "JavaScript"
substring() method is similar to slice() but does not accept negative
indices.start (inclusive) and end
(exclusive).Example:
let str = "JavaScript is amazing!";
let sub = str.substring(11, 17); // sub is "amazin"
indexOf() method of String values searches this string and returns the index of the
first occurrence of the specified substring.const paragraph = 'The quick brown fox jumps over the lazy dog. If the dog barked, was it really lazy?';
const indexOfFirst = paragraph.indexOf("dog");
console.log(indexOfFirst);
substr() method extracts a specified number of characters from a string.start (inclusive) and the length of the substring.Example:
let str = "OpenAI is innovative!";
let sub = str.substr(8, 2); // sub is "is"
replace() method replaces the first occurrence of a specified substring with another
substring.search string and the replacement string as arguments.Example:
let sentence = "I love JavaScript. JavaScript is powerful.";
let newSentence = sentence.replace("JavaScript", "Node.js");
// newSentence is "I love Node.js. JavaScript is powerful."
replaceAll() method replaces all occurrences of a specified substring with another
substring.search string and the replacement string as arguments.Example:
let sentence = "I love JavaScript. JavaScript is powerful.";
let newSentence = sentence.replaceAll("JavaScript", "Node.js");
// newSentence is "I love Node.js. Node.js is powerful."
toUpperCase() and toLowerCase() are used to convert a string to all uppercase or
all lowercase characters, respectively.Example:
let name = "John Doe";
let upperCaseName = name.toUpperCase(); // "JOHN DOE"
let lowerCaseName = name.toLowerCase(); // "john doe"
concat() method is used to join two or more strings.Example:
let firstName = "John";
let lastName = "Doe";
let fullName = firstName.concat(" ", lastName); // "John Doe"
trim() method removes whitespace (spaces, tabs, line breaks) from both ends of a string.
Example:
let sentence = " This is a sentence with spaces. ";
let trimmed = sentence.trim(); // "This is a sentence with spaces."
charAt(index) returns the character at the specified index in a string.charCodeAt(index) returns the Unicode value of the character at the specified index.Example:
let word = "Hello";
let char = word.charAt(1); // "e"
let charCode = word.charCodeAt(1); // 101 (Unicode value of "e")
split() method splits a string into an array of substrings based on a specified
separator.Example:
let sentence = "I,am,a,comma,separated,sentence";
let words = sentence.split(","); // ["I", "am", "a", "comma", "separated", "sentence"]
JavaScript supports various types of functions, each with its own syntax and use cases. Understanding these functions is essential for writing effective JavaScript code. Here is a detailed explanation of each type:
Definition: Regular functions are the most common type of functions in JavaScript. They are
defined using the function keyword.
Syntax:
function functionName(parameters) {
// function body
}
Example:
function greet(name) {
return `Hello, ${name}!`;
}
console.log(greet("Alice")); // Hello, Alice!
Use Cases: Regular functions are used for most function definitions, including event handlers, methods in objects, and general-purpose functions.
Definition: Arrow functions provide a shorter syntax for writing functions. They do not have
their own this context; instead, they inherit this from the parent scope.
Syntax:
const functionName = (parameters) => {
// function body
};
Example:
const greet = (name) => `Hello, ${name}!`;
console.log(greet("Bob")); // Hello, Bob!
Use Cases: Arrow functions are often used for concise function expressions, especially for callbacks and functional programming.
Difference between Regular Function and Arrow Function:
this Binding: Arrow functions do not have their own this; they
inherit this from the parent scope, whereas regular functions have their own this.
this should not
change, such as callbacks and functional programming.Definition: Anonymous functions are functions without a name. They are often used as arguments to other functions or assigned to variables.
Syntax:
function(parameter) {
// function body
}
Example:
setTimeout(function() {
console.log("Hello, world!");
}, 1000);
Use Cases: Anonymous functions are commonly used as callbacks, event handlers, or immediate invocations.
Definition: Function expressions involve defining a function and assigning it to a variable. They can be named or anonymous.
Syntax:
const functionName = function(parameters) {
// function body
};
Example:
const greet = function(name) {
return `Hello, ${name}!`;
};
console.log(greet("Charlie")); // Hello, Charlie!
Use Cases: Function expressions are used when a function needs to be assigned to a variable, passed as an argument, or returned from another function.
Definition: A callback function is a function passed as an argument to another function and is executed after some operation has been completed.
Syntax:
function callback() {
// function body
}
function mainFunction(callback) {
// execute callback
callback();
}
Example:
function logMessage() {
console.log("This is a callback function.");
}
function executeCallback(callback) {
callback();
}
executeCallback(logMessage);
Use Cases: Callback functions are widely used in asynchronous programming, event handling, and functional programming.
Definition: JavaScript treats functions as first-class citizens, meaning they can be assigned to variables, passed as arguments, and returned from other functions.
Example:
function greet(name) {
return `Hello, ${name}!`;
}
const sayHello = greet;
console.log(sayHello("Dave")); // Hello, Dave!
Use Cases: This property of functions allows for higher-order functions, functional programming, and creating flexible APIs.
Definition: A higher-order function is a function that accepts other functions as arguments or returns a function.
Syntax:
function higherOrderFunction(callback) {
// function body
}
Example:
function higherOrderFunction(callback) {
callback();
}
function logMessage() {
console.log("This is a higher-order function.");
}
higherOrderFunction(logMessage);
Use Cases: Higher-order functions are used in functional programming, array methods like
map, filter, and reduce.
Definition: A self-invoking function, also known as an Immediately Invoked Function Expression (IIFE), is a function that is executed immediately after it is defined.
Syntax:
(function() {
// function body
})();
Example:
(function() {
console.log("This is an IIFE.");
})();
Use Cases: IIFEs are used to create a local scope and avoid polluting the global namespace.
Difference between Regular Function and Self-Invoking Function:
const person = {
name: "Alice",
regularFunction: function() {
console.log(this.name); // Alice
},
arrowFunction: () => {
console.log(this.name); // undefined (inherits `this` from the global scope)
}
};
person.regularFunction();
person.arrowFunction();
// Regular Function
function regularFunction() {
console.log("This is a regular function.");
}
regularFunction(); // This is a regular function.
// Self-Invoking Function (IIFE)
(function() {
console.log("This is an IIFE.");
})(); // This is an IIFE.
Definition: Scope refers to the context in which variables are declared and accessed. In JavaScript, there are two main types of scope:
Global Scope: Variables declared outside of any function or block have a global scope. They can be accessed from any part of the code.
var globalVariable = "I am global";
function exampleFunction() {
console.log(globalVariable); // Accessible inside functions
}
console.log(globalVariable); // Accessible globally
Local Scope (Function Scope): Variables declared within a function have local scope. They are only accessible within that function.
function exampleFunction() {
var localVariable = "I am local";
console.log(localVariable); // Accessible inside the function
}
console.log(localVariable); // Error: localVariable is not defined
Definition: Scope chaining refers to the ability of a function to access variables from its own scope, the scope of the function it was declared within, and the global scope.
var globalVar = "I am global";
function outerFunction() {
var outerVar = "I am outer";
function innerFunction() {
var innerVar = "I am inner";
console.log(innerVar); // Access innerVar
console.log(outerVar); // Access outerVar
console.log(globalVar); // Access globalVar
}
innerFunction();
console.log(innerVar); // Error: innerVar is not defined
}
outerFunction();
console.log(outerVar); // Error: outerVar is not defined
Definition: Shadowing occurs when a variable declared within a local scope has the same name as a variable in an outer scope. The inner variable "shadows" the outer one within its scope.
var outerVar = "I am outer";
function exampleFunction() {
var innerVar = "I am inner";
console.log(innerVar); // Access innerVar
console.log(outerVar); // Access outerVar from the outer scope
var outerVar = "I am inner's shadow"; // This shadows the outerVar
console.log(outerVar); // Access the innerVar's shadow
}
exampleFunction();
Shadowing in JavaScript occurs when a variable declared within a local scope has the same name as a variable in an outer scope, effectively "shadowing" the outer variable within its scope. While shadowing can be a source of confusion and bugs if used carelessly, there are situations where it can be intentionally employed for specific purposes. Here are some use cases for shadowing:
Local Variable Modification:
var count = 10;
function updateCount() {
var count = 20; // Shadowing the outer 'count'
console.log(count); // Outputs 20
}
updateCount();
console.log(count); // Outputs 10 (outer 'count' remains unchanged)
In this case, the inner function has its own count variable that shadows the outer
count, allowing modification within its scope.
Parameter Shadowing:
var x = 5;
function addX(x) {
return x + 10; // 'x' here shadows the outer 'x'
}
console.log(addX(3)); // Outputs 13 (inner 'x' is used as a parameter)
Nested Function Definitions:
function outerFunction() {
var message = "Hello from outer";
function innerFunction() {
var message = "Hello from inner"; // Shadowing 'message' from outer scope
console.log(message); // Outputs "Hello from inner"
}
innerFunction();
console.log(message); // Outputs "Hello from outer"
}
outerFunction();
In this example, the inner function has its own message variable, which shadows the
message from the outer scope.
Avoiding Global Scope Pollution:
var data = "Global data";
function processData(data) {
// 'data' parameter shadows the global 'data'
console.log(data); // Outputs the function parameter
}
processData("Local data");
In this case, the local data parameter shadows the global data, providing a
clear separation between local and global contexts.
Definition: A closure is a function that has access to variables from its own scope, the scope of the function it was declared within, and the global scope. Closures allow for the preservation of the outer function's state even after the outer function has finished executing.
function outerFunction() {
var outerVar = "I am outer";
function innerFunction() {
var innerVar = "I am inner";
console.log(outerVar); // Access outerVar from the outer scope
console.log(innerVar); // Access innerVar
}
return innerFunction; // Return the inner function (closure)
}
var closure = outerFunction();
closure(); // Executes innerFunction with access to outerVar and innerVar
In this example, innerFunction is returned from outerFunction and assigned to
closure. Even though outerFunction has finished executing, closure
still has access to outerVar due to the closure mechanism.
Understanding these concepts is crucial for writing efficient and maintainable JavaScript code.
Scope chaining and closures are related concepts in JavaScript, but they are not exactly the same. Let's clarify the difference between them:
Definition: Scope chaining refers to the process by which a function can access variables not only within its own scope but also in the outer scopes in which it was defined.
Mechanism: When a function is invoked, JavaScript looks for variables in its local scope. If a variable is not found, it looks in the outer (enclosing) scope. This process continues until the variable is found or the global scope is reached.
Example:
var globalVar = "I am global";
function outerFunction() {
var outerVar = "I am outer";
function innerFunction() {
console.log(innerVar); // Access innerVar
console.log(outerVar); // Access outerVar from the outer scope
console.log(globalVar); // Access globalVar
}
innerFunction();
}
outerFunction();
Definition: A closure is a function that "closes over" variables from its outer scope, preserving access to those variables even after the outer function has finished executing.
Mechanism: A closure is created when a function is defined inside another function, and the inner function references variables from the outer function. The inner function maintains a reference to the outer function's variables, creating a closure.
Example:
function outerFunction() {
var outerVar = "I am outer";
function innerFunction() {
console.log(outerVar); // Access outerVar from the closure
}
return innerFunction; // Return the inner function (closure)
}
var closure = outerFunction();
closure(); // Executes innerFunction with access to outerVar from the closure
Scope chaining is the mechanism that allows a function to access variables in its lexical scope chain, while closures are the result of a function having access to variables from its outer scope even after the outer function has finished executing.
Closure is a concept that involves scope chaining but is not limited to it. A closure is formed when a function retains access to variables from its outer scope, creating a closure even if it doesn't explicitly reference variables from the outer scope in its code.
Class in JavaScript:
Definition: A class is a blueprint for creating objects with a predefined structure and behavior. It encapsulates data (properties) and functions (methods) that operate on that data.
Syntax:
class ClassName {
constructor(parameters) {
// constructor code
}
method1() {
// method1 code
}
method2() {
// method2 code
}
}
Example:
class Animal {
constructor(name) {
this.name = name;
}
speak() {
console.log(`${this.name} makes a sound.`);
}
}
const dog = new Animal('Dog');
dog.speak(); // Output: Dog makes a sound.
Inheritance in JavaScript:
Definition: Inheritance is a mechanism that allows a class (subclass/derived class) to inherit properties and methods from another class (superclass/base class).
Syntax:
class Subclass extends Superclass {
constructor(parameters) {
super(parameters); // Call the superclass constructor
// subclass constructor code
}
// additional methods specific to the subclass
}
Example:
class Bird extends Animal {
constructor(name, wingspan) {
super(name); // Call the superclass constructor
this.wingspan = wingspan;
}
fly() {
console.log(`${this.name} is flying with a wingspan of ${this.wingspan} cm.`);
}
}
const eagle = new Bird('Eagle', 200);
eagle.speak(); // Output: Eagle makes a sound.
eagle.fly(); // Output: Eagle is flying with a wingspan of 200 cm.
First-Class Functions:
In programming languages, a language is said to have first-class functions if functions are treated as first-class citizens. This means functions can be:
Example of First-Class Functions:
// Function assigned to a variable
const greet = function(name) {
return `Hello, ${name}!`;
};
// Function passed as an argument to another function
function processGreeting(greeterFunction, name) {
return greeterFunction(name);
}
// Function returned from another function
function createGreeter(greeting) {
return function(name) {
return `${greeting}, ${name}!`;
};
}
// Using first-class functions
const result1 = processGreeting(greet, "John");
console.log(result1); // Output: Hello, John!
const customGreeter = createGreeter("Hi");
const result2 = customGreeter("Alice");
console.log(result2); // Output: Hi, Alice!
High-Order Functions:
A higher-order function is a function that takes one or more functions as arguments or returns a function as its result.
Example of High-Order Functions:
// Higher-order function taking a function as an argument
function multiplier(factor) {
return function(number) {
return number * factor;
};
}
const double = multiplier(2);
const triple = multiplier(3);
console.log(double(5)); // Output: 10
console.log(triple(5)); // Output: 15
// Higher-order function returning a function
function greeterFactory(greeting) {
return function(name) {
return `${greeting}, ${name}!`;
};
}
const sayHello = greeterFactory("Hello");
const sayHi = greeterFactory("Hi");
console.log(sayHello("Tom")); // Output: Hello, Tom!
console.log(sayHi("Jerry")); // Output: Hi, Jerry!
Key Differences:
First-Class Functions:
High-Order Functions:
function marker(func) {
return function(a, b) {
console.log("======");
func(a, b);
console.log("======");
};
}
function sum(a, b) {
console.log(a + b);
}
const wrap = marker(sum);
wrap(2, 3); // Now you can call wrap, which in turn calls sum with the wrapping behavior
Objects are stored and copied by reference, unlike primitives which are copied by value.
{ name }
instead of { name: name }.{ [keyName]: value } for dynamic keys.user?.address?.city - safely access nested props
without crashing.{}.Example:
let user = { // an object
name: "John", // by key "name" store value "John"
age: 30 // by key "age" store value 30
};
A property has a key (also known as “name” or “identifier”) before the colon ":" and a value to the right of it.
In the user object, there are two properties:
The first property has the name "name" and the value "John". The second one has the name "age" and the value 30.
console.log(user.name)//John
Structure and Organization: Objects allow you to group related data and functions together, providing a way to structure your code.
Easy Access: You can access properties and methods using their names (keys), making it easy to retrieve or modify data.
Flexibility: Objects can store data of different types and can be modified dynamically, making them versatile for various use cases.
Properties: Keys in an object are called properties, and their corresponding values can be of any data type.
Methods: Functions within an object are known as methods. They allow objects to encapsulate behavior.
Accessing Properties and Methods: Use dot notation (object.property) or
bracket notation (object['property']) to access object members.
Example:
let person = {
name: "John",
age: 30,
greet: function() {
return `Hello, my name is ${this.name}.`;
},
};
console.log(person.name); // "John"
console.log(person.greet()); // "Hello, my name is John."
Modeling Real-World Entities: Objects are suitable for modeling real-world entities, like users, products, or vehicles, where you can represent properties and actions.
Configuration: Objects are used to store configuration settings for applications.
Data Structures: Objects are often used as data structures for organizing, storing, and retrieving data efficiently.
Object Literals: The most common way to create an object is by defining it using object literals, as shown in the syntax example.
Using the new Operator: You can create objects from constructor functions
using the new operator.
Object.create(): You can create objects with a specific prototype using the
Object.create() method.
Adding Methods: You can add methods to an object by assigning function expressions to its properties.
this Keyword: The this keyword refers to the object itself and is often
used to access its own properties and methods.
Accessing Properties: Use dot notation (object.property) or bracket
notation (object['property']) to access object properties.
Adding and Modifying Properties: You can add or modify properties by simply assigning values to them.
Deleting Properties: The delete keyword can be used to remove properties
from an object.
for...in loop to iterate over an object's
properties and perform actions on them.Example:
for (let key in person) {
console.log(key, person[key]);
}
Object.keys(obj)Example:
const person = {
name: "Alice",
age: 28,
job: "Engineer"
};
const keys = Object.keys(person);
console.log(keys); // ["name", "age", "job"]
Object.values(obj)Example:
const person = {
name: "Bob",
age: 35,
job: "Designer"
};
const values = Object.values(person);
console.log(values); // ["Bob", 35, "Designer"]
Object.entries(obj)Example:
const person = {
name: "Carol",
age: 42,
job: "Teacher"
};
const entries = Object.entries(person);
console.log(entries);
// [
// ["name", "Carol"],
// ["age", 42],
// ["job", "Teacher"]
// ]
Object.assign(target, source1, source2, ...)Example:
const target = { a: 1, b: 2 };
const source = { b: 3, c: 4 };
const merged = Object.assign(target, source);
console.log(merged); // { a: 1, b: 3, c: 4 }
Object.create(proto)Example:
const parent = {
greet: function() {
console.log("Hello!");
}
};
const child = Object.create(parent);
child.greet(); // "Hello!"
Object.defineProperty(obj, prop, descriptor)Example:
const person = {};
Object.defineProperty(person, 'name', {
value: "David",
writable: false
});
console.log(person.name); // "David"
person.name = "Eva"; // This assignment will be ignored.
console.log(person.name); // "David"
Object.freeze(obj)Example:
const car = { make: "Toyota", model: "Camry" };
Object.freeze(car);
car.color = "Blue"; // This property addition is ignored.
console.log(car.color); // undefined
Object.seal(obj)Example:
const laptop = { brand: "Dell", model: "XPS" };
Object.seal(laptop);
laptop.price = 1000; // This property addition is ignored.
delete laptop.model; // This property deletion is ignored.
console.log(laptop); // { brand: "Dell", model: "XPS" }
These are just a few of the many methods and functionalities provided by JavaScript objects. Objects are powerful data structures that allow you to work with and manipulate data in a flexible and versatile way. Understanding these methods and how to use them is crucial for JavaScript development.
Object.getOwnPropertyNames(obj)Example:
const person = {
name: "Eve",
age: 25,
[Symbol('id')]: 'unique'
};
const propertyNames = Object.getOwnPropertyNames(person);
console.log(propertyNames); // ["name", "age"]
Object.getOwnPropertyDescriptor(obj, prop)Example:
const person = {
name: "Frank",
age: 30
};
const descriptor = Object.getOwnPropertyDescriptor(person, 'name');
console.log(descriptor);
// {
// value: "Frank",
// writable: true,
// enumerable: true,
// configurable: true
// }
Object.is(obj1, obj2)Example:
console.log(Object.is(5, 5)); // true
console.log(Object.is(NaN, NaN)); // true
console.log(Object.is(0, -0)); // false
Object.getOwnPropertySymbols(obj)Example:
const person = {
[Symbol('id')]: 'unique',
[Symbol('code')]: '12345'
};
const symbols = Object.getOwnPropertySymbols(person);
console.log(symbols); // [Symbol(id), Symbol(code)]
Object.entries(obj)[key, value] pairs as arrays.
Example:
const person = {
name: "Hannah",
age: 40,
job: "Engineer"
};
const entries = Object.entries(person);
console.log(entries);
// [
// ["name", "Hannah"],
// ["age", 40],
// ["job", "Engineer"]
// ]
Object.values(obj)Example:
const person = {
name: "Isaac",
age: 45,
job: "Artist"
};
const values = Object.values(person);
console.log(values); // ["Isaac", 45, "Artist"]
Normal method
let obj = {
name:"Raj",
age:24
}
function demo(a){
console.log(a.name,a.age)
}
demo(obj)
After applying call
let obj = {
name:"Raj",
age:24
}
function demo(){
console.log(this.name,this.age)
}
demo.call(obj)
`this` keyword refers to the particular object.
let obj = {
name:"Raj",
age:24
}
function demo(company,jobrole){
console.log(this.name,this.age,company,jobrole)
}
demo.call(obj,"Google","Developer")
let obj = {
name:"Raj",
age:24
}
function demo(company,jobrole){
console.log(this.name,this.age,company,jobrole)
}
demo.apply(obj,["Google","Developer"])
let obj = {
name:"Raj",
age:24
}
function demo(company,jobrole){
console.log(this.name,this.age,company,jobrole)
}
const value = demo.bind(obj)
value("Google","Developer");
An array of objects in JavaScript is a collection where each item is an object. This structure is particularly useful for handling a list of records where each record has the same set of properties. Here’s an example:
let users = [
{ name: "Alice", age: 25, city: "New York" },
{ name: "Bob", age: 30, city: "San Francisco" },
{ name: "Charlie", age: 35, city: "Chicago" }
];
In this example, users is an array containing three objects. Each object represents a user with
properties name, age, and city.
Find a user by name: Write a function to find a user by their name from the array of objects.
function findUserByName(users, name) {
return users.find(user => user.name === name);
}
console.log(findUserByName(users, "Bob"));
// Output: { name: 'Bob', age: 30, city: 'San Francisco' }
Filter users by age: Write a function to get all users above a certain age.
function filterUsersByAge(users, minAge) {
return users.filter(user => user.age > minAge);
}
console.log(filterUsersByAge(users, 28));
// Output: [{ name: 'Bob', age: 30, city: 'San Francisco' }, { name: 'Charlie', age: 35, city: 'Chicago' }]
Sort users by age: Write a function to sort the users by age in ascending order.
function sortUsersByAge(users) {
return users.sort((a, b) => a.age - b.age);
}
console.log(sortUsersByAge(users));
// Output: [{ name: 'Alice', age: 25, city: 'New York' }, { name: 'Bob', age: 30, city: 'San Francisco' }, { name: 'Charlie', age: 35, city: 'Chicago' }]
Get a list of cities: Write a function to extract the list of cities from the array of users.
function getCities(users) {
return users.map(user => user.city);
}
console.log(getCities(users));
// Output: ['New York', 'San Francisco', 'Chicago']
Calculate the average age: Write a function to calculate the average age of the users.
function calculateAverageAge(users) {
const totalAge = users.reduce((sum, user) => sum + user.age, 0);
return totalAge / users.length;
}
console.log(calculateAverageAge(users));
// Output: 30
Add a new user: Write a function to add a new user to the array.
function addUser(users, newUser) {
users.push(newUser);
return users;
}
let newUser = { name: "Dave", age: 28, city: "Los Angeles" };
console.log(addUser(users, newUser));
// Output: Updated array with the new user added
Update a user’s age: Write a function to update the age of a user given their name.
function updateUserAge(users, name, newAge) {
let user = users.find(user => user.name === name);
if (user) {
user.age = newAge;
}
return users;
}
console.log(updateUserAge(users, "Alice", 26));
// Output: Updated array with Alice's age updated to 26
Definition: A Set is basically a collection of unique values, i.e., one value can occur only once in a Set. If we try to insert a value that is already present in the Set, it is simply ignored. The values stored in a Set can be of any type, whether it is a primitive type or object references.
Why should we use : The benefits of using a Set come down to the optimization and performance benefits. Sets are internally implemented as hash tables or search trees that give us a constant O(1) or O(logN) lookup time in searching an element. Although different browsers or JavaScript engines may implement Set differently, it is always guaranteed to give us time complexity better than O(N).
So if you are working with a large collection of values and you are only concerned with the unique values, using a Set is your best bet. With that being said, let us look at how we can create Sets in JavaScript and carry out different operations that we can perform on them.
Constructor: new Set(iterable) where iterable is an optional
iterable object (e.g., an array) that provides the initial values for the set.
You can create a Set in JavaScript in two ways:
You can create an empty Set object using the new keyword as follows:
const myNewSet = new Set();
You can also initialize a Set with values by passing an array to the constructor:
const myNewSet = new Set(["here", "are", "are", "some", "values"]);
console.log([...myNewSet]); // ["here", "are", "some", "values"]
You can even create a Set of unique characters in a string by passing the string to the Set constructor:
const myNewSet = new Set("here");
console.log([...myNewSet]); // ["h", "e", "r"]
To add new values to a Set, you can use the add() method on the Set object:
const myNewSet = new Set([1, 4, 6]);
myNewSet.add(7); // added
myNewSet.add(1); // already exists in Set, ignored
console.log([...myNewSet]); // [1, 4, 6, 7]
You can remove a specific value from a Set using the delete() method. The method returns
true if an element is removed and false if the element is not found in the Set:
const myNewSet = new Set([1, 4, 6]);
console.log(myNewSet.delete(1)); // true
console.log(myNewSet.delete(5)); // false
console.log([...myNewSet]); // [4, 6]
To remove all elements from a Set and make it empty, you can use the clear() method:
const myNewSet = new Set([1, 4, 6]);
myNewSet.clear();
console.log([...myNewSet]); // []
You can check if a value exists in the Set by calling the has() method. It returns
true if the value exists and false otherwise:
const myNewSet = new Set([1, 4, 6]);
console.log(myNewSet.has(1)); // true
console.log(myNewSet.has(5)); // false
There are a few ways to loop through each element of a Set. You can use the forEach() method or
a for...of loop:
forEach()const myNewSet = new Set([1, 4, 6]);
myNewSet.forEach(element => {
console.log(element);
});
for...of Loopconst myNewSet = new Set([1, 4, 6]);
for (const element of myNewSet) {
console.log(element);
}
You can view the number of elements present in a Set by using the size property:
const myNewSet = new Set([1, 4, 6]);
console.log(myNewSet.size); // 3
You can convert a Set to an Iterator by calling the values() method on the Set object. This
method returns an iterator with all the elements of the Set:
const myNewSet = new Set([1, 4, 6]);
const iterator = myNewSet.values();
for (const element of iterator) {
console.log(element);
}
Here are some important methods and properties of Sets:
new Set(): Create a new Set object.add(): Add a new element to the Set.has(): Check if an element is present in the Set.delete(): Delete a specified value from the Set.clear(): Delete all elements from the Set.forEach(): Run a specified function for every element of the Set.values(): Return an Iterator with all the values present in the Set.size: Property to check the number of elements in the Set.
### Common Set Methods
1. `add(value)`: Adds a new element with the specified value to the set. It returns the set itself.
**Example:**
```javascript
const mySet = new Set();
mySet.add(1).add(2).add(3);
delete(value): Removes an element with the specified value from the set. Returns
true if the element was in the set and false otherwise.
Example:
mySet.delete(2); // Removes 2 from the set
has(value): Checks whether an element with the specified value exists in the set. Returns
true if found, false if not.
Example:
mySet.has(3); // Returns true
clear(): Removes all elements from the set.
Example:
mySet.clear(); // Clears the set
size: Returns the number of elements in the set.
Example:
const setSize = mySet.size; // Returns the size of the set
Map is another built-in object in JavaScript that allows you
to store key-value pairs. It can have keys of any data type.new Map(iterable) where iterable is an optional
iterable object (e.g., an array of key-value pairs) that provides the initial values for the map.set(key, value): Sets the value for the specified key in the map. Returns the map itself.
Example:
const myMap = new Map();
myMap.set("name", "Alice").set("age", 28);
get(key): Returns the value associated with the specified key, or undefined if
the key is not found.
Example:
const name = myMap.get("name"); // Returns "Alice"
delete(key): Removes the key-value pair with the specified key from the map. Returns
true if the key was found and removed, false otherwise.
Example:
myMap.delete("age"); // Removes the key "age" and its associated value
has(key): Checks whether a key exists in the map. Returns true if found,
false if not.
Example:
myMap.has("name"); // Returns true
clear(): Removes all key-value pairs from the map.
Example:
myMap.clear(); // Clears the map
size: Returns the number of key-value pairs in the map.
Example:
const mapSize = myMap.size; // Returns the size of the map
Loops are used in JavaScript to perform repeated tasks based on a condition. Conditions typically return true or false when analysed. A loop will continue running until the defined condition returns false.
for (let i = 0; i < 5; i++) {
console.log("Iteration " + i);
}
let i = 0;
while (i < 5) {
console.log(i);
i++;
}
Prototypes are the mechanism by which JavaScript objects inherit features from one another. Every object in JavaScript has a built-in property, which is called its prototype.
const person = {
greet() { console.log("Hello!"); }
};
const student = Object.create(person);
student.greet(); // "Hello!" (inherited)
JavaScript is a single-threaded language, meaning it can only do one thing at a time. The Event Loop is the secret sauce that allows JS to be non-blocking and handle asynchronous operations.
console.log('Start');
setTimeout(() => console.log('Timeout'), 0);
Promise.resolve().then(() => console.log('Promise'));
console.log('End');
// Output: Start -> End -> Promise -> Timeout
A Closure is the combination of a function bundled together with references to its surrounding state (the lexical environment).
function makeCounter() {
let count = 0;
return function() {
return ++count;
};
}
const counter = makeCounter();
console.log(counter()); // 1
console.log(counter()); // 2
A Promise represents the eventual completion (or failure) of an asynchronous operation.
const getData = new Promise((resolve, reject) => {
const success = true;
if(success) resolve("Data received!");
else reject("Error!");
});
Syntactic sugar over Promises that makes asynchronous code look synchronous.
async function fetchUser() {
try {
const response = await fetch('https://api.github.com/users/octocat');
const data = await response.json();
console.log(data.name);
} catch (error) {
console.error("Fetch failed", error);
}
}