KEMBAR78
JS Key Points | PDF | Java Script | Anonymous Function
0% found this document useful (0 votes)
22 views19 pages

JS Key Points

JavaScript is a high-level, lightweight scripting language used for interactive web applications, featuring dynamic typing, event-driven execution, and cross-platform compatibility. TypeScript, a superset of JavaScript, adds static typing for improved code quality and maintainability. The document also covers asynchronous programming concepts, including callbacks, promises, and async/await, as well as various JavaScript features and best practices.

Uploaded by

realvikram7
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)
22 views19 pages

JS Key Points

JavaScript is a high-level, lightweight scripting language used for interactive web applications, featuring dynamic typing, event-driven execution, and cross-platform compatibility. TypeScript, a superset of JavaScript, adds static typing for improved code quality and maintainability. The document also covers asynchronous programming concepts, including callbacks, promises, and async/await, as well as various JavaScript features and best practices.

Uploaded by

realvikram7
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/ 19

Javascript Note

What is the Javascript

JavaScript is a high-level, lightweight, interpreted scripting language primarily used


to build interactive and dynamic web applications.

Key Features of JavaScript

●​ Dynamic Typing: Offers flexibility during development but demands discipline


and robust testing at scale.​

●​ Event-Driven and non-blocking: Native support for non-blocking operations


makes it ideal for I/O-heavy applications.​

●​ Lightweight and Interpreted: Executes directly in the browser or runtime


environment without the need for compilation.​

●​ Cross-Platform Execution: Runs seamlessly across all major operating


systems and devices.​

●​ Extensible via Ecosystem: From bundlers like Webpack to frameworks like


React and Next.js, the ecosystem empowers rapid, scalable development.

Advantages of JavaScript

●​ Reduced Server Load: Client-side validations and dynamic rendering minimize


unnecessary server requests.​

●​ Performance: Runs natively in the browser, reducing latency and improving


UX.​

●​ Developer Experience: Intuitive syntax and massive community support


speed up onboarding and prototyping.​

●​ Interactivity: Enables features like live form validation, modals, carousels, and
real-time updates.​

●​ Cross-Environment Compatibility: Can be used across frontend, backend,


mobile (React Native), and even desktop (Electron).​
What is TypeScript?

TypeScript is a strongly typed superset of JavaScript developed by Microsoft. It adds


static typing and other powerful features to JavaScript, which helps developers write
safer, more scalable, and maintainable code.

Key Features of TypeScript:

●​ Static Type Checking


●​ Type Inference
●​ Optional and Default Parameters
●​ Access Modifiers (public, private, protected)
●​ Enums
●​ Advanced Tooling Support

Why Use TypeScript?

●​ Improves code quality and maintainability


●​ Reduces runtime errors
●​ Better developer experience with IDE support
●​ Scales well for large codebases and teams

Synchronous vs Asynchronous Functions

●​ Synchronous:​
In synchronous execution, tasks are executed one at a time. Each operation
blocks the main thread until it completes. This model is simple but inefficient
for I/O-heavy tasks. ​

●​ Asynchronous:​
Asynchronous functions allow non-blocking execution. Tasks like API calls,
file operations, or timers run independently, and the main thread continues
processing other code. This is crucial in modern web development for
maintaining smooth UX.
Callback Functions

●​ Definition:​
A callback is a function passed as an argument to another function. It's
invoked after the completion of a task, especially in asynchronous scenarios.​

●​ Why They Matter:​


Callbacks are the foundation of asynchronous JavaScript, enabling tasks like
API calls or event handling without blocking the main thread.​

●​ Drawbacks (Callback Hell):​


When callbacks are deeply nested, the code becomes unreadable and hard to
maintain. This is known as "callback hell" — a common anti-pattern.​

Promises

●​ Definition:​
A Promise is an object that represents the eventual result of an asynchronous
operation. It has three states: pending, fulfilled, and rejected.​

●​ Why We Use Promises:​

○​ Promotes cleaner code than deeply nested callbacks.


○​ Makes chaining multiple async operations more manageable.
○​ Provides .then() for success and .catch() for error handling.​

●​ Limitation:​
While better than callbacks, chaining multiple .then() blocks can still make the
logic hard to follow.

Promise.all

Promise.all() is used when we want multiple asynchronous tasks to be


completed in parallel, and only proceed when all of them are resolved. It’s useful
when the tasks are independent but we need all the results.

Promise.allSettled()

Promise.allSettled() is used when we want multiple asynchronous tasks to


run in parallel and we want the result of each one, regardless of whether they
succeed or fail. It’s useful when we want to process partial success or show fallback
options.
Promise.any()

Promise.any() is used when we want multiple asynchronous tasks to run in


parallel, and we only care about the first successful result, ignoring any failures. It’s
useful for redundant or fallback systems where one success is enough.

Promise.race()

Promise.race() is used when we want multiple asynchronous tasks to run in


parallel, and we proceed as soon as the first one settles — whether it resolves or
rejects. It’s useful in time-sensitive scenarios where speed matters more than
outcome.

Async/Await

●​ Definition:​
async and await are ES6+ features that allow writing asynchronous code that
looks and behaves like synchronous code.​

●​ Why It's Preferred:​

○​ Readability: Code appears linear and easier to debug.​

○​ Error Handling: Standard try...catch syntax allows consistent and clean


error management.​

○​ Improved Maintainability: Easier for teams to collaborate and scale


codebases.

Callback Hell (In Depth)

When callbacks are deeply nested, the code becomes unreadable and hard to
maintain. This is known as "callback hell" — a common anti-pattern.​

This typically occurs when performing sequential async operations without using
better abstractions like Promises or async/await.

When would you prefer Promises over async/await?

While both serve the same purpose — managing async code — the choice depends
on context and control flow requirements.
🔹 Prefer Promises when:
Parallel Execution / Batch Processing

If you're firing multiple async calls in parallel, Promise.all, Promise.race, etc.,


are more declarative and optimized.

Chaining Based APIs:

For library-style APIs or utility functions, using .then() maintains chainability


and allows optional catch handlers at each stage.

Conditional Async Execution: Sometimes, returning a Promise from within a utility


function gives more flexibility to consumers (they can choose whether or not to
await).

🔹 Prefer async/await when:


1.​ Sequential Flow:​
When tasks are dependent on the result of previous ones, async/await
provides clean, readable flow.

2. Error Handling with try/catch:

●​ More consistent with how we handle sync errors — especially useful in


complex functions or controllers.

3. Readability & Debugging:

●​ Easier to follow and debug compared to nested .then() chains.

What are call(), apply(), and bind() in JavaScript?


These methods are used to manipulate this keyword when invoking a function. In
JavaScript, this depends on how a function is called, not where it’s defined.

1. call()

●​ Immediately invokes the function with a specified this value and arguments
passed individually.​
●​ Useful when we want to borrow a method from another object or override the
default context.

2. apply()

●​ Same as call(), but it accepts arguments as an array.​

●​ Typically useful when arguments are already in an array (e.g., spread from
user input or dynamic data).​

3. bind()

●​ Doesn't invoke the function immediately.​

●​ Returns a new function with the bound this context.​

●​ Ideal when you want to delay execution — especially in event handling or


callback scenarios.

What are Arrow Functions in JavaScript?

Arrow functions, introduced in ES6, are a concise and modern way to define
functions.

Key Characteristics of Arrow Functions:

1. No Own this Context

Arrow functions don’t have their own this. Instead, they lexically bind this — meaning
they inherit it from their surrounding scope.

This is especially useful in React, where you often work with nested callbacks or
closures.

2. No arguments Object

Arrow functions don't have their own arguments object. If you need to work with
arguments, you'd typically use the rest operator:

3. Not Suitable as Constructors

Because arrow functions don’t have their own this, they can’t be used with new.
They’re not constructible.
Why Arrow Functions Matter in React

🔸 1. Cleaner Syntax in Functional Components.


🔸 2. Avoiding Manual bind() in Class Components
🔸 3. Avoiding Common Mistakes with this in Callbacks
When Not to Use Arrow Functions

1.​ Object Methods (if this is needed dynamically): Arrow functions bind this
lexically, which may not be the desired behavior inside object methods.​

2.​ Dynamic Contextual this (like in event delegation or libraries expecting


dynamic binding): Avoid arrow functions when you rely on this to refer to the
calling context.​

LocalStorage vs SessionStorage vs Cookies

LocalStorage

●​ Stores data in key-value pairs and persists even after the browser is closed.​

●​ Storage limit: ~5–10 MB depending on the browser.​

●​ Synchronous API.​

●​ Not sent with HTTP requests.

sessionStorage

●​ Same key-value structure as localStorage but scoped to a single session/tab.​

●​ Data is cleared when the tab or browser is closed.​

●​ Storage limit: similar to localStorage.​

●​ Not sent with HTTP requests.​


✅ Cookies
●​ Also key-value pairs, but sent along with every HTTP request (unless marked
as HttpOnly or scoped to a specific path/domain).​

●​ Size is much smaller (~4 KB).​

●​ Can be set with expiration or be session-based.​

●​ Can be marked as Secure, SameSite, and HttpOnly.

Axios vs Fetch API (Simple Definition):

●​ Fetch API: Built-in browser method to make HTTP requests. It's simple but
needs manual work for JSON parsing and error handling.​

●​ Axios: A third-party library that makes HTTP requests easier with built-in
JSON parsing, better error handling, timeouts, and features like interceptors.

Why I prefer Axios in production:

●​ Automatic JSON data transformation: Axios automatically converts the data


to and from JSON, so we don’t have to manually parse or stringify it.
●​ Response timeout: Axios allows us to set a timeout for our requests, so we
can handle errors if the server takes too long to respond.
●​ HTTP interceptors: Axios allows us to intercept requests and responses
before they are handled by then or catch, so we can modify them or add
additional logic.
●​ Download progress: Axios allows us to track the progress of our downloads
and uploads, so we can display feedback to the user or cancel the request if
needed.
●​ Simultaneous requests: Axios allows us to make multiple requests at the
same time and combine them into a single response using axios.all and
axios.spread.
What is Currying in JavaScript?

Currying is a functional programming pattern where a function that accepts multiple


arguments is transformed into a sequence of unary (single-argument) functions.

Why We Use Currying (Real-World Use Cases):

🔹 1. Reusability & Partial Application


You can partially apply a function to preset some arguments, enhancing reusability
in large-scale applications.

🔹 2. Improved Readability & Testability


Curried functions break down complex logic into smaller, testable, composable
pieces — making the codebase easier to read and maintain, which is a priority at
scale.

🔹 3. Real Use in Libraries


Libraries like Redux, Ramda, and even React event handlers often use or benefit
from curried-style function composition.

let vs var vs const — Key Differences (Senior Summary)

Feature var let const

Scope Function-scoped Block-scoped Block-scoped

Hoisting Hoisted (value: Hoisted (in TDZ* Hoisted (in TDZ*)


undefined) state)

Re-declarati ✅ Allowed ❌ Not allowed ❌ Not allowed


on

Reassignme ✅ Allowed ✅ Allowed ❌ Not allowed


nt (constant value)
TDZ (Temporal Dead Zone): Variables declared with let and const are hoisted
but cannot be accessed until declaration is evaluated. Accessing them
beforehand throws a ReferenceError.

When to Use What

●​ 🔹 var — Avoid in modern JS. Legacy only.​


●​ 🔹 let — Use when value will be reassigned (e.g., loop counters, toggling
flags).​

●​ 🔹 const — Use by default. Ensures immutability of reference, which leads to


fewer bugs and predictable behavior.​

ES6 Features

1. Block-Scoped Declarations (let and const)

Prior to ES6, JavaScript had only function-scoped variables via var, which often led to
bugs due to unexpected hoisting or accidental variable overrides.​
ES6 introduced let and const, which are block-scoped, helping us enforce better
scoping rules and safer code.

●​ let is mutable, block-scoped.​

●​ const is immutable for primitive values and ensures the binding can't be
reassigned, which is great for enforcing immutability patterns.​

Real-life Use Case:​


In large codebases, especially in modular architecture, let and const prevent global
leakage and make variable lifecycles more predictable—crucial for debugging and
refactoring.

2. Arrow Functions

Arrow functions provide a more concise syntax and also lexically bind the this
context, which removes common pitfalls around function context in callbacks.
Senior Insight:​
This eliminates the need for .bind(this) or self = this hacks, especially in event
handlers, React components, or Node.js services.

3. Default Parameters

Default function parameters simplify handling of optional arguments and reduce


boilerplate.

Use Case:​
Common in utility functions, backend API defaults, or component prop defaults in
frameworks like React.

4. Destructuring

Destructuring allows concise syntax for extracting values from objects or arrays.

Advanced Use Case:​


Useful in function parameters to directly extract needed values:

As a senior, I use this pattern extensively when working with React props, Redux
selectors, and utility modules.

5. Spread and Rest Operators

Spread (...)

●​ Shallow Copying of arrays/objects​

●​ Merging arrays/objects

Rest (...)

●​ Aggregates remaining items into an array or object.


●​ Powerful for variadic functions and selective destructuring.​

Senior Insight:​
I often use spread in Redux reducers for immutability and rest in utility libraries for
flexible APIs.

6. Promises & Async/Await


Promises introduced cleaner asynchronous control compared to nested callbacks.​
Async/Await took it further by allowing sequential-looking code with asynchronous
behavior.

Senior-Level Usage:

●​ Async/await is now the standard for writing readable and maintainable async
flows.
●​ Combined with Promise.all, it's a powerful pattern for parallel execution.​

7. Iterators and Generators

Iterators:

Custom iterable logic. When we define [Symbol.iterator], we can control how an


object is traversed.

Generators (function*)

Functions that can pause using yield and resume later.​


They simplify asynchronous flows and lazy evaluations.

function* idGenerator() {

let id = 0;

while (true) yield id++;

Real-world Use Cases:

●​ Implementing infinite scroll or pagination in frontend apps.


●​ In Redux Saga, generator functions elegantly manage side effects like API
calls.
●​ In complex pipelines (e.g., ETL or file processing), generators help control
flow without exhausting memory.​
setTimeout

Executes code after a specified delay. It's event-loop based and non-blocking.

setInterval

setInterval(fn, delay) repeatedly invokes the function fn every delay milliseconds.

Shallow vs Deep Copy

🧪 Shallow Copy
●​ Copies only the top-level properties.
●​ Nested objects are still references to the original.​

Risk: Mutating nested structures affects the original.

🧬 Deep Copy
●​ Recursively copies all levels, ensuring complete independence.​

Approaches:

1.​ JSON.parse(JSON.stringify(obj)) — simple, but:​

○​ Loses functions, Dates, undefined, Maps, Sets, etc.​

2.​ _.cloneDeep(obj) (Lodash) — robust and recommended for production.


3.​ Structured cloning (structuredClone(obj) in modern JS) — a native deep copy
method.​

🧰 Framework vs Library
Framework

●​ framework provides a predefined application structure.


●​ Can have multiple libraries.
●​ Example: Angular
Library

●​ the developer integrates it as needed


●​ Can ‘t use any framework.
●​ Example: React, Lodash, Axios​

🧾 Parameters vs Arguments
●​ Parameters are variables listed in the function definition.​

●​ Arguments are actual values passed during function invocation.

function greet(name) { // name = parameter

console.log("Hello " + name);

greet("John"); // "John" = argument

🧠 Higher-Order Functions
A higher-order function:

●​ Takes a function as input


●​ Or returns a function

Use Cases:

●​ Array methods: .map(), .filter(), .reduce()


●​ Function composition in libraries like Redux or Lodash
●​ Enhancers in HOCs (Higher Order Components) in React​

Senior Perspective:
"Higher-order functions enable clean separation of concerns and make
business logic modular and reusable — a pattern I often leverage in
complex UI behaviors."

🔒 Closures
A closure allows a function to access its lexical scope even after its outer function
has returned.

Verification: Use console.dir(fn) in Chrome DevTools to inspect the closure scope.

Real Use Case: Maintaining private state in a module or memoization logic.

🪄 Hoisting
Hoisting is JS's compile-time behavior where:

●​ Function declarations and var declarations are moved to the top of their
scope.
●​ let/const are hoisted but remain in the Temporal Dead Zone (TDZ) until they’re
defined.​

Order of Precedence:

1.​ Function declarations​

2.​ var declarations​

3.​ let/const (hoisted but uninitialized)​

🧯 Destructuring
Allows unpacking values from arrays or properties from objects into distinct
variables.

⚙️ JavaScript Event Loop (Complete Flow)


The Event Loop is the mechanism that ensures non-blocking I/O in JS by:

Here's how it works:


1.​ Call Stack​

○​ Runs all synchronous code one line at a time.​

2.​ Web APIs / Browser APIs​

○​ When we call setTimeout, fetch, or similar, the actual work is done


by the browser outside JS, so the Call Stack stays free.​

3.​ Task Queues​

○​ Microtask Queue: Handles Promises, MutationObserver.​

○​ Callback Queue (or Macrotask Queue): Handles setTimeout,


setInterval, etc.​

4.​ Event Loop​

👉
○​ Keeps checking:​

👉
Is the Call Stack empty?​

👉
If yes, first run all microtasks​
Then run one macrotask (like a timeout)​

👨‍🔧 Web Workers in JavaScript


Web Workers run JS in a separate thread — useful for:

●​ Heavy computations
●​ Parsing large data sets
●​ Keeping the main UI thread responsive

How it works:

1.​ Create a worker file (e.g., worker.js)


2.​ Initialize it in the main thread:

const worker = new Worker('worker.js');

worker.postMessage(data);
worker.onmessage = (e) => { console.log(e.data); };

React Integration:

●​ Use libraries like react-web-worker​

●​ Or custom hooks with Worker instances

JavaScript Prototypes & Prototypal Inheritance

In JavaScript, every object has an internal property called its prototype.

A prototype is just another object from which other objects inherit properties and
methods.

Prototype inheritance means an object can inherit properties and methods from another
object using its prototype chain.

stopPropagation() & preventDefault()

✋ event.stopPropagation()
Stops the event from bubbling up (or capturing down) the DOM tree.

Use Case in React:

Imagine you have a modal component with a close button, and clicking inside the
modal should not close it (but clicking the overlay should).

🚫 event.preventDefault()
Prevents the default browser behavior of an event — often used in form submissions
or anchor tags.

✅ Debounce vs Throttle
🔹 Debounce
●​ 📝 Definition:Delays a function call until after a certain time has passed since
●​ 🎯 Use Case: Ideal for search inputs, window resizing, or auto-saving after
the last event.

user stops typing.​


●​ 🕒 Behavior: Waits until the user stops triggering the event for a specified
delay.

🔹 Throttle
●​ 📝 Definition: Limits a function to run only once every set interval, no matter
how many times the event occurs..​

●​ 🎯 Use Case: Great for scroll events, drag events, or rate-limiting button
clicks.​

●​ 🕒 Behavior: Executes at most once per time interval, regardless of how


many times triggered.

Commonly used in React props, API response handling, and Redux state selectors.

What is Event Delegation?

Event delegation means you attach a single event listener to a parent element
instead of attaching it to each individual child element. This makes your code more
efficient.

🌀 Event Capturing vs Bubbling


Capture Phase

●​ Event travels from root → target (useCapture: true)

Bubble Phase

●​ Default; event travels from target → root

element.addEventListener('click', handler, true); // Capture


element.addEventListener('click', handler); // Bubble
Real Use Case: Event delegation, preventing undesired propagation, and
accessibility enhancements.

You might also like