0% found this document useful (0 votes)
14 views

JS-NOTES

js notes

Uploaded by

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

JS-NOTES

js notes

Uploaded by

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

VAR-LET-CONST

TEMPORAL DEADZONE- The


term Temporal Dead Zone
(TDZ) in JavaScript refers to the
time between the creation of a
variable (when it's scoped) and
its initialization with a value.
During this period, the variable
exists but cannot be accessed,
leading to a ReferenceError if
you try to use it.

This happens with variables


declared using let and const.
Unlike var, which is hoisted
and initialized with undefined,
let and const are hoisted but
remain uninitialized in the TDZ.

var is least strict let is more


strict and const is the most
strict in their application

(const should be declared and initialized at same time unlike var and const otherwise it gives type error)

(you cant declare element two time using let and const it gives syntax error unlike var where we can declare
duplicates and it overwrited previous declaration)

(can not access element declared using let otherwise it gives reference error)

(we should use const and let mostly to avoid temporal deadzone we should declare and initialize our variable in the
beginning)

TYPES OF ERRORS

Syntax Error: Occurs when code violates JavaScript syntax rules. Example: let x = ; (missing value).

Type Error: Happens when a value is used in an inappropriate way. Example: null.length (accessing a property of
null).

Reference Error: Arises when accessing an undeclared variable. Example: console.log(y) (y is not defined).
DATA-TYPES IN JAVASCRIPT

Primitive data types (e.g., int, float, char, boolean, etc.) in Java are indeed stored in the stack when they are local
variables.

Complex data types (objects, arrays, etc.) are stored in the heap, but their references (or memory addresses) are
stored in the stack.

Q1 weather let and const is hoisted ?


Yes, let and const are hoisted, but they behave differently from var. Although they are hoisted to the top of their
block scope, they remain in a "temporal dead zone" (TDZ) until the actual line where they are declared. This means
you cannot access them before their declaration.

Key differences in hoisting:

• var: Hoisted and initialized with undefined. You can access it before its declaration, but it will have the value
undefined until assigned.

a. console.log(a); // undefined
b. var a = 5;
c. console.log(a); // 5

• let and const: Hoisted, but not initialized. If you try to access them before their declaration, a ReferenceError
will be thrown due to the temporal dead zone (TDZ).

1. console.log(b); // ReferenceError: Cannot access 'b' before initialization


2. let b = 10;
3. console.log(c); // ReferenceError: Cannot access 'c' before initialization
4. const c = 15;

Summary:

• let and const are hoisted, but you cannot use them until the line where they are declared because they are in
the temporal dead zone.

• var is hoisted and initialized with undefined, allowing access before declaration (though not recommended).
FOREACH VS MAP
BLOCKSCOPE AND SHADOWING IN JS

Block Scope in JavaScript

Block scope refers to the accessibility of variables inside a specific block (i.e., between {}). Variables declared within a
block are only accessible inside that block and not outside.
Example of Block Scope:

1. {
2. let x = 10;
3. console.log(x); // 10
4. }
5. console.log(x); // Error: x is not defined
In this example, x is declared using let inside the block, so it can only be accessed inside that block.

JavaScript has three types of declarations:

1. var: It has function scope, meaning the variable is available throughout the function or globally if declared
outside any function.
2. let: It has block scope, meaning the variable is confined to the block it's declared in.
3. const: Similar to let, it also has block scope, but its value cannot be reassigned.
Example with var (Function Scope):

1. {
2. var y = 20;
3. }
4. console.log(y); // 20
In this case, y is declared with var and can be accessed outside the block due to function scope.

Shadowing in JavaScript

Shadowing occurs when a variable declared inside a block (local scope) has the same name as a variable declared
outside that block (in an outer scope). The inner variable "shadows" or overrides the outer variable inside the block.

Example of Shadowing:

1. let a = 50; // Outer variable


2. {
3. let a = 100; // Shadowing the outer variable
4. console.log(a); // 100 (inner `a` shadows outer `a` within this block)
5. }
6. console.log(a); // 50 (outer `a` is still accessible outside the block)
In this example, the inner a shadows the outer a within the block, but the outer a is still accessible after the block.

Shadowing with var:

1. var b = 30;
2. {
3. var b = 60; // This redefines `b` in the outer scope (no block scope in `var`)
4. console.log(b); // 60
5. }
6. console.log(b); // 60 (outer `b` is also changed)
With var, shadowing actually redefines the outer variable, because var doesn’t have block scope.

Key Points:

• Block Scope: Variables declared with let or const are confined to the block they're declared in.

• Shadowing: When an inner variable shares the same name as an outer variable, it overrides the outer
variable within the block, but doesn’t affect it outside the block if let or const are used.

CLOSURE IN JS
A closure in JavaScript is a function that "remembers" its lexical scope, even when the function is executed outside
that scope. In other words, closures allow a function to access variables from its outer (enclosing) function even after
the outer function has returned.

How Closures Work

When a function is created inside another function, the inner function retains access to the variables of the outer
function. This behavior forms a closure.

Example of a Closure

1. function outerFunction() {
2. let outerVariable = "I'm outside!";
3. function innerFunction() {
4. console.log(outerVariable); // Accesses `outerVariable` from outerFunction's scope
5. }
6. return innerFunction; // Returning the inner function
7. }
8. const closureFunction = outerFunction();
9. closureFunction(); // Output: "I'm outside!"

Uses of Closures:
• Module Design Pattern
• Currying
• Functions like once
• memoize
• maintaining state in async world
• setTimeouts
• Iterators
• and many more...
CALL, BIND, APPLY
In JavaScript, call(), apply(), and bind() are methods used to control the value of this and invoke functions in different
contexts. They are primarily used when you want to borrow methods from one object and apply them to another, or
when you want to explicitly specify what this refers to.

call()
The call() method allows you to invoke a function immediately, and you can explicitly set the value of this within that
function. You can also pass arguments to the function individually.
Syntax:

functionName.call(thisArg, arg1, arg2, ...);


Example:

const person = {
fullName: function() {
return this.firstName + " " + this.lastName;
}
};

const person1 = {
firstName: "John",
lastName: "Doe"
};

console.log(person.fullName.call(person1)); // John Doe


In this example, person.fullName is called with person1 as its this context, allowing it to use person1's properties.

apply()
The apply() method works similarly to call(), but it accepts an array of arguments instead of passing them individually.
Syntax:
js
Copy code
functionName.apply(thisArg, [arg1, arg2, ...]);
Example:
js
Copy code
const numbers = [5, 6, 2, 3, 7];

const max = Math.max.apply(null, numbers); // Finds the max value from the array
console.log(max); // 7
Here, apply() is used to pass an array of numbers to Math.max.

bind()
The bind() method creates a new function where this is permanently set to the value you pass as its first argument.
Unlike call() and apply(), bind() does not invoke the function immediately. Instead, it returns a new function that can
be called later with the specified this context.
Syntax:
const newFunction = functionName.bind(thisArg, arg1, arg2, ...);

Example:
const person = {
firstName: "Jane",
lastName: "Doe",
fullName: function() {
return this.firstName + " " + this.lastName;
}
};

const printFullName = person.fullName.bind(person);


console.log(printFullName()); // Jane Doe
In this example, bind() creates a new function printFullName with this permanently bound to the person object. You
can call it later and it will always refer to person.

Key Differences:

• call(): Invokes the function immediately, passing this and arguments individually.
• apply(): Invokes the function immediately, passing this and arguments as an array.
• bind(): Returns a new function with this bound to the provided object, but does not invoke the function
immediately.

Example Comparison:

1. const person = {
2. fullName: function(city, country) {
3. return this.firstName + " " + this.lastName + ", " + city + ", " + country;
4. }
5. };

6. const person1 = {
7. firstName: "John",
8. lastName: "Doe"
9. };
10. // Using call
11. console.log(person.fullName.call(person1, "New York", "USA"));
12. // Output: John Doe, New York, USA
13. // Using apply
14. console.log(person.fullName.apply(person1, ["New York", "USA"]));
15. // Output: John Doe, New York, USA
16. // Using bind
17. const bindFullName = person.fullName.bind(person1, "New York", "USA");
18. console.log(bindFullName());

19. // Output: John Doe, New York, USA

In the above examples:


• call() and apply() invoke the function immediately.
• bind() creates a new function with preset this and arguments for later invocation.
FUNCTIONS IN JS

1. Function Statement (Function Declaration)


A function statement defines a function with a name.

1. function greet() {
2. console.log("Hello!");
3. }
4. greet(); // Output: Hello!

2. Function Expression
A function expression defines a function and assigns it to a variable.

1. const greet = function() {


2. console.log("Hello!");
3. };
4. greet(); // Output: Hello!

The difference between function declarations and function expressions in JavaScript is how they are hoisted.

• Function declarations are hoisted entirely. During the memory allocation phase (the first step of execution),
both the function's name and its definition are stored in memory, meaning the function can be called before
its declaration in the code.

• Function expressions, on the other hand, are treated like variables. The variable that holds the function is
hoisted, but its value is not initialized until the execution phase. During memory allocation, the variable is set
to undefined, so trying to call the function before the expression is reached in the code will result in an error.

3. Function Description (Comment)


A function description is just a comment explaining what a function does.

1. // This function prints "Hello!"


2. function greet() {
3. console.log("Hello!");
4. }

4. Anonymous Function
An anonymous function is a function without a name. It's often used in function expressions.

1. const greet = function() {


2. console.log("Hello!");
3. };
4. greet(); // Output: Hello!

5. Named Function Expression


This is a function expression with a name, used for debugging or recursion within the expression.

1. const greet = function sayHello() {


2. console.log("Hello!");
3. };
4. greet(); // Output: Hello!
5. // sayHello(); // Error, not accessible outside

6. Parameter vs. Argument


• Parameter: The variable in the function definition.

• Argument: The actual value passed to the function.

1. function greet(name) { // 'name' is a parameter


2. console.log("Hello " + name);
3. }
4. greet("Alice"); // "Alice" is an argument

7. First-Class Functions
Functions are treated like any other value. They can be assigned to variables, passed as arguments, or returned from
other functions.

1. function greet() {
2. return "Hello";
3. }
4. const greetFunc = greet; // Assigned to variable
5. console.log(greetFunc()); // Output: Hello

8. Arrow Functions
A shorter syntax for writing functions. It does not have its own this context.

1. const greet = () => {


2. console.log("Hello!");
3. };
4. greet(); // Output: Hello!
CURRYING IN JS

Currying is a higher-order function technique in JavaScript that transforms a function with multiple arguments into a
series of nested functions, each taking a single argument. This process creates a new function that returns a new
function until all arguments have been provided, finally executing the original function with the collected arguments.

Key Points:

• Currying involves breaking down a function with multiple arguments into a chain of functions, each accepting
a single argument.

• The returned function from each step takes the next argument and returns another function until all
arguments are provided.

• The final function in the chain executes the original function with the accumulated arguments.

Example:(using closures)

1. let multiply = function (x) {


2. return function (y) {
3. console. log(x * y);
4.
5. let multiplyByTwo = multiply(2);
6. multiplyByTwo(3);
7.

Example:(using bind method)

1. let multiply = function (x, y)


2. console.log(x * y) ;
3.
4. let multiplyByTwo multiply.bind(this, 2);
5. multiplyByTwo(3);
6.
7. let multiplyByThree = multiply.bind(this, 3);
8. multiplyByThree(5);

Explanation:

1. The add function takes two arguments, x and y, and returns their sum.

2. The curriedAdd function takes a single argument, x, and returns a new function.

3. The returned function takes a single argument, y, and returns the sum of x and y.
4. By calling curriedAdd(5), we create a new function that is pre-bound to the value 5. This new function takes a
single argument, y, and adds 5 to it.

5. Calling add5(3) passes the value 3 to the newly created function, resulting in the calculation 5 + 3, which
returns 8.

Benefits of Currying:

• Code Reusability: Currying allows you to create reusable functions that can be partially applied with different
arguments.

• Improved Readability: Curried functions can often be more readable and easier to understand, especially
when dealing with complex function compositions.

• Functional Programming Style: Currying is a common technique in functional programming, promoting a


declarative style of programming.

Is javascript single threaded or multithreaded?

Java is single threaded and event driven.

JavaScript is single-threaded by nature, meaning it executes code on a single thread in a sequential manner.
However, it achieves asynchronous behavior using an event loop, allowing it to handle tasks like I/O operations (file
reading, network requests, timers) without blocking the main thread.

How does JavaScript achieve concurrency?

JavaScript uses:

1. Event Loop: It runs in a single thread, but asynchronous operations like setTimeout, Promises, or I/O don't
block execution. These tasks are sent to the browser's or Node.js's environment, and when they are
completed, the event loop picks up the result and processes it.

2. Web Workers: JavaScript can run scripts in the background on separate threads using web workers (in
browsers) or worker threads (in Node.js). However, these workers don’t share memory with the main thread,
which is why they are not true multithreading in the traditional sense (like shared-memory concurrency).

Summary:

• Single-threaded in terms of its runtime (one main thread).

• Can handle asynchronous tasks using the event loop and callback queue.

• Web workers enable parallelism, but not shared-memory multithreading.

CALL BACK FUNCTION IN JAVASCRIPT


A callback function in JavaScript is a function that is passed as an argument to another function and is executed after
that function completes. This is particularly useful for asynchronous operations, like fetching data from an API or
waiting for a user event (e.g., a button click), where you don’t want the program to wait idly for the operation to
finish.

Key Points:

1. Synchronous Callbacks:

o These are executed immediately after the higher-order function finishes its execution. For example,
the forEach() method takes a callback that is executed synchronously for each element in an array.

javascript

Copy code

const arr = [1, 2, 3];

arr.forEach(function(num) {

console.log(num);

});

2. Asynchronous Callbacks:

o These are executed after the higher-order function completes its execution, typically in a future
event cycle (such as when data has been fetched). Examples include setTimeout(), setInterval(), and
HTTP requests (like using fetch or XMLHttpRequest).

javascript

Copy code

setTimeout(function() {

console.log('Executed after 2 seconds');

}, 2000);

3. Importance in Asynchronous Programming:

o JavaScript is single-threaded, meaning it processes tasks one at a time. Callback functions help
ensure the program doesn’t freeze while waiting for long-running operations like network requests.

ES6 Arrow Functions in JavaScript

In JavaScript, ES6 Arrow Functions provide a more concise syntax for writing functions. They are written using the =>
syntax and are especially useful for simplifying function expressions. Here are some key points about arrow
functions:

1. Concise Syntax:

1. Arrow functions allow for a shorter syntax compared to traditional function expressions.
2. Example:

2. // Traditional function expression


3. const sum = function(a, b) {
4. return a + b;
5. };

• // Arrow function
• const sum = (a, b) => a + b;

6. Implicit Return:

1. If the function body contains only a single expression, the return keyword and curly braces can be
omitted.

2. Example:

• const square = x => x * x;

7. Lexical this Binding:

1. Arrow functions do not have their own this context. Instead, they inherit this from the surrounding
code. This makes them especially useful in callbacks, where the this value might otherwise change.

2. Example:

1. const obj = {
2. value: 10,
3. increment: function() {
4. setTimeout(() => {
5. this.value++;
6. console.log(this.value);
7. }, 1000);
8. }
9. };
10. obj.increment(); // After 1 second, logs 11

8. No arguments Object:

1. Arrow functions do not have an arguments object. If you need the arguments of a function, you can
use rest parameters (...args).

9. Usage Restrictions:

1. Arrow functions cannot be used as constructors and will throw an error if used with the new
keyword.

2. They are not suitable for methods in an object when you need the method to have its own this.

Overall, arrow functions make writing short functions simpler and provide clearer behavior when it comes to this and
context handling.
Use of arrow function in js
Using normal function

1. var that = this;


2. this.val = 1;
3. setTimeout (function(){
4. that.val++;
5. console.log(that.val)
6. }, 1)
7. };
8. var xx = new x();

Using fat arrow function

1. var x = function () {
2. this.val = 1;
3. setTimeout (() => {
4. this.val++;
5. console. log(this.val
6. }, 1)
7. };
8. var xx = new x();

fat arrow function does not have this functionality therefore it uses its parents this
How does fat arrow and normal function behave differently

Let’s walk through a specific use case where arrow functions shine, particularly when dealing with this context inside
objects or callbacks, such as in an event handler or a timer.

Use Case: Managing this inside Callbacks

Imagine you have an object that keeps track of a counter and wants to increase this counter every second. A classic
scenario would involve using setInterval to repeatedly execute a function at a given interval. However, in such cases,
normal functions and arrow functions behave quite differently due to how they handle this.

Scenario with a Normal Function:

Here, we'll use a normal function in setInterval, and you’ll see how this behaves unexpectedly.

1. const counter = {
2. count: 0,
3. increment: function () {
4. setInterval(function () {
5. this.count++; // `this` refers to the global object, not `counter`
6. console.log(this.count); // NaN or undefined behavior
7. }, 1000);
8. }
9. };
10. counter.increment();

Problem:

• Issue with Normal Function: The normal function inside setInterval has its own this context. It doesn't refer
to the counter object but to the global object (or undefined in strict mode). This means the code doesn’t
behave as expected because it’s trying to increment count on the wrong object.

o Output will likely be NaN or undefined because this.count does not refer to the counter object.

Solution with Arrow Function:

Let’s fix this problem using an arrow function.

1. const counter = {
2. count: 0,
3. increment: function () {
4. setInterval(() => {
5. this.count++; // `this` correctly refers to the `counter` object
6. console.log(this.count); // increments as expected
7. }, 1000);
8. }
9. };
10. counter.increment();

Why Arrow Functions Work Here:

• Lexical this: The arrow function inside setInterval doesn’t have its own this. It inherits this from the
surrounding context, which is the increment method of the counter object. As a result, this.count correctly
refers to counter.count.

• Correct Behavior: Now, every second, the count property on the counter object is incremented as expected,
and the output will be 1, 2, 3, 4....
...

Why This Matters:

• Cleaner Code: Without arrow functions, you would typically need to store this in a separate variable (often
called self or that) or use .bind(this) to achieve the same behavior in a normal function.

1. const counter = {
2. count: 0,
3. increment: function () {
4. const self = this; // capture the `this` value
5. setInterval(function () {
6. self.count++; // works, but less clean
7. console.log(self.count);
8. }, 1000);
9. }
10. };

• Simplicity and Readability: Arrow functions allow you to avoid these extra steps, making your code more
straightforward and readable.

Summary:

In this use case, arrow functions are very useful when you need to maintain the correct this context inside callback
functions, such as in event handlers, timers (setInterval or setTimeout), or asynchronous code. They eliminate the
need for workarounds like .bind(this) or saving this in another variable.

Would you like to explore more advanced use cases for arrow functions or normal functions?

Asynchronous JavaScript & EVENT LOOP

simple breakdown of JavaScript's asynchronous execution model and the concepts related to the event loop, call
stack, web APIs, async tasks, and more:

1. JavaScript Engine Execution and Call Stack

• JavaScript Engine: Executes JS code; popular ones include V8 (Chrome) and SpiderMonkey (Firefox).

• Call Stack: A data structure where the JS engine keeps track of function calls. Think of it as a stack of plates
where each function call gets "pushed" on top and "popped" off when completed.

• Main Job of Call Stack: Keeps track of where the engine is in the code. When a function is called, it goes on
the stack; when it finishes, it’s removed.

Example:

1. function greet() {
2. console.log("Hello");
3. }
4. greet(); // greet() is pushed to the stack, then popped off after executing

2. Asynchronous Tasks and JavaScript Execution


• JS is single-threaded, meaning it executes one task at a time. But it handles asynchronous tasks (like fetching
data) with Web APIs and Event Loop.

• Asynchronous tasks (e.g., setTimeout, fetch) are handed over to the browser's Web APIs for processing so
they don’t block the main thread.

3. Web APIs in JavaScript

• Web APIs (provided by the browser) handle async operations outside of JS’s single thread.

• Examples: setTimeout, fetch, DOM events, console.log.

• Web APIs manage these tasks and notify the JS engine when they’re ready.

4. How setTimeout Works in JavaScript

1. Call setTimeout: The function and delay time are sent to Web API.

2. Timer: Web API starts a timer without blocking JS execution.

3. Callback Queue: Once the timer is done, the callback is moved to the Callback Queue.

4. Event Loop: Waits until the Call Stack is empty, then moves the callback from Callback Queue to Call Stack for
execution.

Example:

1. console.log("Start");
2. setTimeout(() => console.log("Delayed"), 1000); // Web API handles timer
3. console.log("End");
4. Output: "Start" → "End" → "Delayed" (after 1 second)

5. Event Loop and Callback Queue

• Event Loop: Continuously checks if the Call Stack is empty and if there are tasks in the Callback Queue
waiting to be executed.

• Callback Queue: Stores async callback functions (like from setTimeout) that are ready to be executed but
wait for the Call Stack to be free.

Why Needed: JS is single-threaded, so Event Loop manages async tasks without blocking code execution.

6. How Event Listeners Work in JavaScript

• Event listeners (e.g., click, keyup) are handled by Web APIs.

• When an event occurs, the callback is placed in the Callback Queue and waits for the Event Loop to push it to
the Call Stack.

Example:

1. button.addEventListener("click", () => console.log("Button clicked"));

When the button is clicked, the callback is executed only when the Call Stack is empty.
7. More About the Event Loop

• Ensures async tasks execute only when the Call Stack is empty.

• Continuous Cycle: Keeps running as long as there are tasks in the Callback Queue or Microtask Queue.

8. How fetch() Works in JavaScript

• fetch() calls are handled by the Web API.

1. Web API: Starts the network request.

2. Microtask Queue: When data returns, the fetch callback goes to the Microtask Queue, which has higher
priority than the Callback Queue.

9. Microtask Queue and Microtasks

• Microtask Queue: Holds async callbacks from promises (then) and MutationObserver.

• Higher Priority: Microtasks are always cleared before any Callback Queue tasks.

• Starvation Issue: If Microtasks keep adding tasks, Callback Queue might get "starved" (never executed).

Example:

2. Promise.resolve().then(() => console.log("Microtask"));


3. setTimeout(() => console.log("Macro task"), 0);
4. Output: "Microtask" → "Macro task" (Microtasks run first).

10. Starvation of Functions in Callback Queue

• Callback Queue Starvation: If new Microtasks keep arriving (e.g., many .then() calls), Callback Queue tasks
like setTimeout may never run.

• Balance: JS balances async tasks by emptying Microtask Queue first, then moving to Callback Queue.

Summary

1. Call Stack: Executes synchronous code.

2. Web APIs: Manage async tasks (e.g., setTimeout, fetch).

3. Callback Queue: Holds async callbacks like setTimeout.

4. Microtask Queue: Higher priority queue for promises and microtasks.

5. Event Loop: Manages the Call Stack, Callback Queue, and Microtask Queue for smooth execution.
WEB API’S

JavaScript alone is limited in its functionality and doesn’t have built-in capabilities for handling things like networking
or file manipulation. Web APIs provide a bridge between JavaScript and the browser’s more complex features,
allowing web apps to behave more like fully-featured software applications.

Web APIs (Application Programming Interfaces) are pre-built interfaces provided by the browser that allow JavaScript
to interact with various system features, perform complex tasks, and manage asynchronous operations without
blocking the main thread. They make it possible for JavaScript to perform tasks beyond basic script operations, like
interacting with the web, hardware, storage, or system capabilities.

Here’s a list of essential Web APIs in JavaScript and their functions. These APIs are provided by the browser to handle
various tasks, especially asynchronous operations, independently of the main JavaScript execution thread.
1. Timer APIs
• setTimeout: Delays the execution of a function for a specified number of milliseconds.
• setInterval: Repeatedly calls a function at specified intervals.
• clearTimeout / clearInterval: Stops a setTimeout or setInterval timer.

2. DOM (Document Object Model) APIs


• document: Represents the HTML document; allows manipulation of HTML and CSS.
• getElementById, querySelector, etc.: Used to select elements in the DOM.
• createElement, appendChild, etc.: Allow creation and insertion of new elements.
• addEventListener: Attaches event listeners to elements for various events (click, scroll, etc.).

3. Fetch API
• fetch(): Sends HTTP requests to retrieve or send data to/from a server. It returns a promise, which resolves to a Response object.
• Response.json() / Response.text(): Parses response data into JavaScript-readable formats.

4. XMLHttpRequest API
• XMLHttpRequest: Legacy method for making HTTP requests. Provides more control than fetch() but is more complex and typically
replaced by Fetch API.

5. Console API
• console.log, console.error, console.warn: Used to output messages to the browser’s console for debugging.

6. Geolocation API
• navigator.geolocation.getCurrentPosition: Retrieves the user’s current location.
• navigator.geolocation.watchPosition: Monitors location changes in real-time.

7. Local Storage API


• localStorage: Stores data in the browser with no expiration date (persistent even after closing the browser).
• sessionStorage: Stores data that persists only within a browser session (cleared when the tab is closed).

8. IndexedDB API
• IndexedDB: A low-level API for storing large amounts of structured data (e.g., databases). Useful for offline storage of large datasets.

9. History API
• history.pushState / history.replaceState: Allows manipulation of the browser’s session history (useful for single-page applications).
• history.back / history.forward: Navigates backward or forward in the browser history.

10. Notification API


• Notification.requestPermission: Requests permission from the user to display notifications.
• new Notification(): Displays notifications to the user (e.g., chat app alerts).

11. Canvas API


• <canvas> element and methods: Used for rendering 2D graphics, animations, and complex visualizations (e.g., games) on a webpage.

12. WebSocket API


• WebSocket: Creates a persistent connection between the browser and server for real-time data transfer, useful in live updates (e.g.,
chat or stock tickers).

13. Web Workers API


• Worker: Enables running JavaScript in the background on a separate thread, useful for handling heavy computations without blocking
the main thread.

14. File API


• FileReader: Reads files from the user’s local system, typically used with <input type="file">.
• Blob: Represents raw data that can be read as text or binary.

15. URL API


• URL: Provides utilities to parse, construct, and manipulate URLs (e.g., extracting query parameters).

16. Device Orientation API


• window.ondeviceorientation: Detects orientation of the device (e.g., tilting a phone).
• window.ondevicemotion: Detects motion data from the device’s accelerometer.

17. Battery Status API


• navigator.getBattery(): Returns information about the device’s battery (e.g., charging status, battery level).

18. Clipboard API


• navigator.clipboard.writeText / readText: Provides access to the clipboard to copy and paste text.

19. Speech Recognition API


• SpeechRecognition: Transcribes spoken words into text, useful for voice commands and accessibility.

20. MutationObserver API


• MutationObserver: Watches for changes in the DOM (e.g., element added, removed, or attribute changed).

SPREAD OPERATOR IN JS
The spread operator (...) in JavaScript (and other languages with similar syntax) is used to expand or unpack elements
from an array or properties from an object. It is particularly useful for creating new arrays or objects by copying or
merging existing ones. Here’s how it works in both contexts:

Key Points:

• Shallow Copy: The spread operator performs a shallow copy, so nested objects or arrays inside the copied
object or array still refer to the same instances.

• Order Matters: When merging objects, the order of spreading affects which properties are overridden.

• Immutability: The spread operator is often used in functional programming to keep data immutable by
creating new copies rather than modifying existing objects or arrays.

The spread operator makes code more readable and reduces the need for complex loops or helper functions when
dealing with arrays and objects.

USES OF SPREAD OPERATOR


1. Copying an Array

1. const arr = [1, 2, 3];


2. const copyArr = [...arr];
3. console.log(copyArr); // Output: [1, 2, 3]

2. Merging Two Arrays

1. const arr1 = [1, 2];


2. const arr2 = [3, 4];
3. const mergedArr = [...arr1, ...arr2];
4. console.log(mergedArr); // Output: [1, 2, 3, 4]

3. Adding Elements to an Array

1. const arr = [2, 3];


2. const newArr = [1, ...arr, 4];
3. console.log(newArr); // Output: [1, 2, 3, 4]

4. Copying an Object

1. const obj = { a: 1, b: 2 };
2. const copyObj = { ...obj };
3. console.log(copyObj); // Output: { a: 1, b: 2 }

5. Merging Two Objects

1. const obj1 = { a: 1, b: 2 };
2. const obj2 = { b: 3, c: 4 };
3. const mergedObj = { ...obj1, ...obj2 };
4. console.log(mergedObj); // Output: { a: 1, b: 3, c: 4 }

6. Adding New Properties to an Object

1. const obj = { a: 1, b: 2 };
2. const newObj = { ...obj, c: 3 };
3. console.log(newObj); // Output: { a: 1, b: 2, c: 3 }

7. Function Arguments as Array Elements

1. function add(x, y, z) {
2. return x + y + z;
3. }
4. const numbers = [1, 2, 3];
5. console.log(add(...numbers)); // Output: 6

8. Removing Elements from an Array

You can remove elements by combining the spread operator with array destructuring.

1. const arr = [1, 2, 3, 4];


2. const [first, ...rest] = arr;
3. console.log(rest); // Output: [2, 3, 4]

Each of these examples showcases the versatility of the spread operator for copying, merging, adding, and
restructuring both arrays and objects in JavaScript!

You might also like