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

JavaScript Closures

Uploaded by

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

JavaScript Closures

Uploaded by

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

JavaScript Closures

Q: What is a JavaScript closure, and how is it used in practical scenarios?

A closure is a function that retains access to its lexical scope, even when the function is executed
outside that scope.

Example:

javascript
Copy code
function outerFunction(outerVariable) {
return function innerFunction(innerVariable) {
console.log('Outer Variable:', outerVariable);
console.log('Inner Variable:', innerVariable);
};
}

const newFunction = outerFunction('outside');


newFunction('inside');

Explanation: The innerFunction maintains access to the outerVariable even after


outerFunction has finished executing.

Memoization in JavaScript

Q: What is memoization in JavaScript, and how can it optimize function performance?

Memoization is an optimization technique that stores the results of expensive function calls and
returns the cached result when the same inputs occur again.

Example:

javascript
Copy code
function memoize(fn) {
const cache = {};
return function(...args) {
const key = JSON.stringify(args);
if (cache[key]) {
return cache[key];
}
const result = fn(...args);
cache[key] = result;
return result;
};
}

const factorial = memoize(function(n) {


if (n === 0) return 1;
return n * factorial(n - 1);
});

console.log(factorial(5)); // 120
console.log(factorial(5)); // Cached 120

Event Loop and Call Stack

Q: Explain the difference between the event loop and the call stack in JavaScript.

Event Loop: Manages asynchronous operations by checking the call stack and callback queue.

Call Stack: Holds function calls, performs function execution.

Example:

javascript
Copy code
console.log('Start');

setTimeout(() => {
console.log('Callback');
}, 0);

console.log('End');

Explanation: 'Start' and 'End' are logged first due to synchronous execution. 'Callback' is
executed last, managed by the event loop.

Generators in JavaScript

Q: What are Generators in JavaScript, and how do they work?

Generators are special functions that can be paused and resumed.

Example:

javascript
Copy code
function* generatorFunction() {
yield 'Hello';
yield 'World';
}

const gen = generatorFunction();


console.log(gen.next().value); // 'Hello'
console.log(gen.next().value); // 'World'

Explanation: yield pauses the generator. next() resumes it.

“this” Keyword in JavaScript


Q: Explain the principles of the “this” keyword in JavaScript and how it behaves in
different contexts.

“this” refers to the context in which a function is called.

Example:

javascript
Copy code
const obj = {
name: 'Alice',
getName: function() {
return this.name;
}
};

console.log(obj.getName()); // 'Alice'

const getName = obj.getName;


console.log(getName()); // undefined

Explanation: In obj.getName(), this refers to obj. In getName(), this is undefined in strict


mode or window in non-strict mode.

Web Workers

Q: What are Web Workers in JavaScript, and how do they enable multi-threading in web
applications?

Web Workers run scripts in background threads.

Example:

javascript
Copy code
// worker.js
self.onmessage = function(e) {
self.postMessage(e.data * 2);
};

// main.js
const worker = new Worker('worker.js');
worker.onmessage = function(e) {
console.log(e.data); // Output from worker
};
worker.postMessage(10);

Explanation: Web Workers run worker.js independently, enabling multi-threading.

Callback Hell vs Promises


Q: What is the difference between “callback hell” and Promises in JavaScript?

Callback Hell: Pyramid of nested callbacks.

Promises: Flatten async flow, chainable.

Example:

javascript
Copy code
// Callback Hell
doSomething(function(result) {
doSomethingElse(result, function(newResult) {
doThirdThing(newResult, function(finalResult) {
console.log(finalResult);
});
});
});

// Promises
doSomething()
.then(result => doSomethingElse(result))
.then(newResult => doThirdThing(newResult))
.then(finalResult => console.log(finalResult))
.catch(error => console.error(error));

Explanation: Promises simplify async code by avoiding deep nesting.

Module Pattern

Q: Explain the “module pattern” in JavaScript and how it facilitates encapsulation and
modularity.

Module Pattern: Encapsulates private variables/methods.

Example:

javascript
Copy code
const Module = (function() {
let privateVar = 'secret';

function privateMethod() {
console.log(privateVar);
}

return {
publicMethod: function() {
privateMethod();
}
};
})();
Module.publicMethod(); // 'secret'

Explanation: Only publicMethod is exposed, encapsulating privateVar and privateMethod.

Rest and Spread Operators

Q: What are “rest” and “spread” operators in JavaScript, and how do they work?

Rest Operator: Collects arguments into an array. Spread Operator: Expands array into
individual elements.

Example:

javascript
Copy code
// Rest
function sum(...args) {
return args.reduce((acc, val) => acc + val, 0);
}

console.log(sum(1, 2, 3)); // 6

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

Explanation: ...args collects arguments; [...arr] expands array.

Prototype Chain

Q: What is the “prototype chain” in JavaScript, and how does it relate to inheritance?

Prototype Chain: Links objects to share properties/methods.

Example:

javascript
Copy code
function Person(name) {
this.name = name;
}

Person.prototype.greet = function() {
console.log('Hello, ' + this.name);
};

const alice = new Person('Alice');


alice.greet(); // 'Hello, Alice'
Explanation: alice inherits greet from Person.prototype.

Event Loop in JavaScript

Q: What is the Event Loop in JavaScript, and how does it enable asynchronous operations?

Event Loop: Manages execution of code, handling events, and executing queued sub-tasks.

Example:

javascript
Copy code
console.log('Start');

setTimeout(() => {
console.log('Callback');
}, 0);

console.log('End');

Explanation: 'Start' and 'End' log first. 'Callback' logs after, managed by the event loop.

Hoisting in JavaScript

Q: Explain the concept of “Hoisting” in JavaScript. How does it affect variable and
function declarations?

Hoisting: Moves declarations to the top of the scope.

Example:

javascript
Copy code
console.log(a); // undefined
var a = 5;

console.log(b); // ReferenceError: b is not defined


let b = 5;

Explanation: var is hoisted, initialized to undefined. let is not accessible before declaration.

“this” Binding in Arrow Functions

Q: What is the “this” binding in arrow functions compared to regular functions?

Arrow Functions: this is lexically bound, refers to surrounding context.

Example:
javascript
Copy code
const obj = {
value: 10,
regularFunction: function() {
console.log(this.value); // 10
},
arrowFunction: () => {
console.log(this.value); // undefined
}
};

obj.regularFunction();
obj.arrowFunction();

Explanation: regularFunction binds this to obj. arrowFunction binds this to enclosing


scope.

Currying in JavaScript

Q: Explain the concept of “currying” in JavaScript and how it can be used to transform a
function into a series of unary functions.

Currying: Transforms a function into a sequence of functions, each with a single argument.

Example:

javascript
Copy code
function curry(fn) {
return function curried(...args) {
if (args.length >= fn.length) {
return fn(...args);
} else {
return function(...nextArgs) {
return curried(...args, ...nextArgs);
};
}
};
}

function add(a, b) {
return a + b;
}

const curriedAdd = curry(add);


console.log(curriedAdd(1)(2)); // 3

Explanation: curriedAdd transforms add into a series of unary functions.

Observer Pattern
Q: What is the “Observer” pattern in JavaScript, and how can it be used to implement the
Publish-Subscribe model for handling events?

Observer Pattern: Object (subject) maintains a list of dependents (observers) notified of


changes.

Example:

javascript
Copy code
class Subject {
constructor() {
this.observers = [];
}

subscribe(observer) {
this.observers.push(observer);
}

unsubscribe(observer) {
this.observers = this.observers.filter(obs => obs !== observer);
}

notify(data) {
this.observers.forEach(observer => observer.update(data));
}
}

class Observer {
update(data) {
console.log('Received data:', data);
}
}

const subject = new Subject();


const observer = new Observer();

subject.subscribe(observer);
subject.notify('Hello World'); // 'Received data: Hello World'

Explanation: Subject notifies Observer of updates.

Memory Management in JavaScript

Q: How does JavaScript handle memory management, and what are some best practices to
avoid memory leaks?

Memory Management: Automatic with Garbage Collection (GC).

Best Practices:

 Avoid global variables.


 Clear references in closures.
 Use WeakMap and WeakSet for dynamic data.

Example:

javascript
Copy code
let data = {};

function processData() {
let local = {};
data.local = local;
}

processData();
data = null; // Clear reference to allow GC

Explanation: Clearing references helps GC reclaim memory.

localStorage vs sessionStorage

Q: What are the key differences between the “localStorage” and “sessionStorage” in web
storage for storing data in the browser?

localStorage: Persistent data across sessions. sessionStorage: Data per session, cleared on tab
close.

Example:

javascript
Copy code
// localStorage
localStorage.setItem('key', 'value');
console.log(localStorage.getItem('key')); // 'value'

// sessionStorage
sessionStorage.setItem('key', 'value');
console.log(sessionStorage.getItem('key')); // 'value'

Explanation: localStorage persists, sessionStorage is session-specific.

Prototype Property and Constructor Property

Q: Explain how the “prototype” property is used in JavaScript for inheritance and how it
differs from the “constructor” property.

prototype: Shared properties/methods for instances. constructor: Reference to the function that
created the instance.

Example:
javascript
Copy code
function Person(name) {
this.name = name;
}

Person.prototype.greet = function() {
console.log('Hello, ' + this.name);
};

const alice = new Person('Alice');


console.log(alice.constructor); // Person
alice.greet(); // 'Hello, Alice'

Explanation: Person.prototype defines shared methods. alice.constructor points to


Person.

Proxy in JavaScript

Q: What is a “proxy” in JavaScript, and how can it be used to intercept and control access
to objects?

Proxy: Intercepts operations on target objects.

Example:

javascript
Copy code
const target = {
message: 'Hello'
};

const handler = {
get: function(target, property) {
return property in target ? target[property] : 'Property not found';
}
};

const proxy = new Proxy(target, handler);


console.log(proxy.message); // 'Hello'
console.log(proxy.nonexistent); // 'Property not found'

Explanation: Proxy intercepts get operations, customizes behavior.

Destructuring Assignment

Q: What are “destructuring assignment” and “spread/rest operators” in JavaScript, and


how can they simplify working with arrays and objects?

Destructuring Assignment: Extracts values from arrays/objects into variables. Spread/Rest


Operators: Simplify handling collections.
Example:

javascript
Copy code
// Destructuring
const [a, b] = [1, 2];
const {name, age} = {name: 'Alice', age: 25};

// Spread
const arr1 = [1, 2];
const arr2 = [...arr1, 3, 4];

// Rest
function sum(...args) {
return args.reduce((acc, val) => acc + val, 0);
}

console.log(a, b); // 1 2
console.log(name, age); // 'Alice' 25
console.log(arr2); // [1, 2, 3, 4]
console.log(sum(1, 2, 3)); // 6

Explanation: Destructuring extracts values. Spread expands arrays. Rest collects arguments.

Promises in JavaScript

Q: What is a “Promise” in JavaScript, and how does it simplify handling asynchronous


operations?

Promise: Represents future completion of async operation, simplifies chaining.

Example:

javascript
Copy code
const promise = new Promise((resolve, reject) => {
setTimeout(() => {
resolve('Success!');
}, 1000);
});

promise
.then(result => console.log(result)) // 'Success!'
.catch(error => console.error(error));

Explanation: Promise handles async operation, allows chaining with then and catch.

Lazy Loading in JavaScript

Q: What is “lazy loading” in JavaScript, and how can it improve web performance?
Lazy Loading: Defers loading of resources until needed.

Example:

javascript
Copy code
// Lazy load image
const img = document.createElement('img');
img.src = 'path/to/image.jpg';
document.body.appendChild(img);

document.addEventListener('scroll', () => {
if (img.getBoundingClientRect().top < window.innerHeight) {
img.src = 'path/to/high-resolution-image.jpg';
}
});

Explanation: Load low-res initially, high-res when in view.

Singleton Pattern in JavaScript

Q: Explain the “singleton pattern” in JavaScript and its use in ensuring a single instance of
a class is created.

Singleton Pattern: Ensures single instance of a class.

Example:

javascript
Copy code
class Singleton {
constructor() {
if (Singleton.instance) {
return Singleton.instance;
}
this.value = 'Hello';
Singleton.instance = this;
}
}

const instance1 = new Singleton();


const instance2 = new Singleton();

console.log(instance1 === instance2); // true

Explanation: Singleton ensures only one instance is created.

Revealing Module Pattern

Q: What is the “Revealing Module Pattern” in JavaScript, and how does it help create
modular and maintainable code?
Revealing Module Pattern: Encapsulates, exposes public methods/variables.

Example:

javascript
Copy code
const Module = (function() {
let privateVar = 'secret';

function privateMethod() {
console.log(privateVar);
}

function publicMethod() {
privateMethod();
}

return {
publicMethod: publicMethod
};
})();

Module.publicMethod(); // 'secret'

Explanation: Encapsulates private members, exposes public API.

Hoisting with let and const

Q: How does JavaScript handle “hoisting” with “let” and “const” compared to “var,” and
what are the implications for variable declarations?

var: Hoisted, initialized to undefined. let/const: Hoisted, not initialized (TDZ).

Example:

javascript
Copy code
console.log(a); // undefined
var a = 5;

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


let b = 5;

const c = 5;
c = 6; // TypeError: Assignment to constant variable.

Explanation: var is initialized to undefined. let and const have TDZ.

Memoization for Recursive Functions


Q: What is “memoization,” and how can it be implemented to optimize recursive functions
in JavaScript?

Memoization: Caches results of function calls.

Example:

javascript
Copy code
function memoize(fn) {
const cache = {};
return function(...args) {
const key = JSON.stringify(args);
if (cache[key]) {
return cache[key];
}
const result = fn(...args);
cache[key] = result;
return result;
};
}

const fibonacci = memoize(function(n) {


if (n <= 1) return n;
return fibonacci(n - 1) + fibonacci(n - 2);
});

console.log(fibonacci(10)); // 55

Explanation: memoize caches recursive function results.

Immutability in JavaScript

Q: Explain the concept of “immutability” in JavaScript and how it can lead to more
predictable and maintainable code.

Immutability: Objects/values cannot be changed after creation.

Example:

javascript
Copy code
const person = {
name: 'Alice',
age: 25
};

// Shallow copy
const newPerson = Object.assign({}, person);
newPerson.age = 26;

console.log(person.age); // 25
console.log(newPerson.age); // 26

// Deep copy (using JSON for simplicity)


const deepCopy = JSON.parse(JSON.stringify(person));
deepCopy.age = 27;

console.log(person.age); // 25
console.log(deepCopy.age); // 27

Explanation: Immutability avoids side-effects, simplifies state management.

Callbacks and Promises

Q: What are “callbacks” and “promises” in the context of asynchronous programming in


JavaScript, and what are their key differences?

Callbacks: Functions passed as arguments for async tasks. Promises: Objects representing
future completion of async tasks.

Example:

javascript
Copy code
// Callback
function fetchData(callback) {
setTimeout(() => {
callback('Data received');
}, 1000);
}

fetchData(result => console.log(result)); // 'Data received'

// Promise
function fetchData() {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve('Data received');
}, 1000);
});
}

fetchData().then(result => console.log(result)); // 'Data received'

Explanation: Callbacks can lead to callback hell. Promises flatten async code, handle errors.

Garbage Collection in JavaScript

Q: Explain the “garbage collection” process in JavaScript and how it manages memory
resources.

Garbage Collection (GC): Automatically reclaims memory no longer in use.


Example:

javascript
Copy code
let data = { name: 'Alice' };
data = null; // GC can reclaim memory

Explanation: GC detects unreachable objects, frees memory.

Temporal Dead Zone (TDZ)

Q: What is the “Temporal Dead Zone” in JavaScript, and how does it relate to variable
declarations with “let” and “const”?

TDZ: Period between entering scope and variable declaration.

Example:

javascript
Copy code
console.log(a); // ReferenceError: Cannot access 'a' before initialization
let a = 5;

const b = 10;
console.log(b); // 10

Explanation: Accessing a before declaration causes ReferenceError due to TDZ.

Closure in JavaScript

Q: What is a “closure” in JavaScript, and how does it impact variable scope and memory
management?

Closure: Function retaining access to its lexical scope.

Example:

javascript
Copy code
function outerFunction(outerVariable) {
return function innerFunction(innerVariable) {
console.log('Outer Variable:', outerVariable);
console.log('Inner Variable:', innerVariable);
};
}

const newFunction = outerFunction('outside');


newFunction('inside');
Explanation: innerFunction retains access to outerVariable even after outerFunction
finishes.

Asynchronous Generators

Q: What are “asynchronous generators” in JavaScript, and how can they simplify
asynchronous code?

Async Generators: Functions yielding promises, used with for await...of.

Example:

javascript
Copy code
async function* asyncGenerator() {
yield await Promise.resolve(1);
yield await Promise.resolve(2);
yield await Promise.resolve(3);
}

(async () => {
for await (let value of asyncGenerator()) {
console.log(value);
}
})();

Explanation: asyncGenerator simplifies handling async data streams.

Flyweight Pattern

Q: Explain the “Flyweight Pattern” in JavaScript and how it optimizes memory usage by
sharing common parts of objects.

Flyweight Pattern: Shares common object parts to save memory.

Example:

javascript
Copy code
class Flyweight {
constructor(sharedState) {
this.sharedState = sharedState;
}
}

class FlyweightFactory {
constructor() {
this.flyweights = {};
}

getFlyweight(sharedState) {
if (!this.flyweights[sharedState]) {
this.flyweights[sharedState] = new Flyweight(sharedState);
}
return this.flyweights[sharedState];
}
}

const factory = new FlyweightFactory();


const flyweight1 = factory.getFlyweight('shared');
const flyweight2 = factory.getFlyweight('shared');

console.log(flyweight1 === flyweight2); // true

Explanation: Flyweight pattern shares sharedState, reducing memory usage.

requestAnimationFrame

Q: What is “requestAnimationFrame” in JavaScript, and how does it improve the


performance of animations and updates in web applications?

requestAnimationFrame: Schedules animation updates for optimal performance.

Example:

javascript
Copy code
function animate() {
let start = null;

function step(timestamp) {
if (!start) start = timestamp;
let progress = timestamp - start;
// Update animation state
if (progress < 2000) { // Run for 2 seconds
requestAnimationFrame(step);
}
}

requestAnimationFrame(step);
}

animate();

Explanation: requestAnimationFrame synchronizes updates with display refresh rate.

Throttling and Debouncing

Q: Explain the concept of “throttling” and “debouncing” in JavaScript and how they are
used to control the frequency of function calls.
Throttling: Limits function calls to a fixed interval. Debouncing: Delays function calls until
after a delay.

Example:

javascript
Copy code
// Throttle
function throttle(func, limit) {
let inThrottle;
return function() {
const args = arguments;
const context = this;
if (!inThrottle) {
func.apply(context, args);
inThrottle = true;
setTimeout(() => inThrottle = false, limit);
}
};
}

// Debounce
function debounce(func, delay) {
let timeout;
return function() {
const args = arguments;
const context = this;
clearTimeout(timeout);
timeout = setTimeout(() => func.apply(context, args), delay);
};
}

Explanation: throttle controls call frequency. debounce delays call until idle.

Reduce Function in JavaScript

Q: What is the “reduce” function in JavaScript, and how can it be used to accumulate
values from an array into a single result?

reduce: Accumulates array values into a single result.

Example:

javascript
Copy code
const numbers = [1, 2, 3, 4, 5];
const sum = numbers.reduce((accumulator, currentValue) => accumulator +
currentValue, 0);

console.log(sum); // 15

Explanation: reduce processes each array element, accumulating a result.


Promise Chaining

Q: Explain the concept of “Promise chaining” in JavaScript and how it simplifies handling
multiple asynchronous operations.

Promise Chaining: Sequential execution of async operations.

Example:

javascript
Copy code
function fetchData() {
return new Promise(resolve => setTimeout(() => resolve('Data received'),
1000));
}

fetchData()
.then(result => {
console.log(result); // 'Data received'
return fetchData();
})
.then(result => {
console.log(result); // 'Data received'
})
.catch(error => console.error(error));

Explanation: Chaining simplifies sequential async operations.

WebSockets

Q: What is “WebSockets” in JavaScript, and how do they enable real-time bidirectional


communication between a client and server?

WebSockets: Protocol for real-time bidirectional communication.

Example:

javascript
Copy code
const socket = new WebSocket('ws://example.com/socket');

socket.onopen = function() {
console.log('Connection opened');
socket.send('Hello Server');
};

socket.onmessage = function(event) {
console.log('Received:', event.data);
};

socket.onclose = function() {
console.log('Connection closed');
};

Explanation: WebSockets enable real-time communication with server.

Array Manipulation with map, filter, and reduce

Q: What is “map”, “filter”, and “reduce” in JavaScript, and how do they compare in terms
of array manipulation?

map: Transforms array elements. filter: Filters array elements. reduce: Accumulates array
elements.

Example:

javascript
Copy code
const numbers = [1, 2, 3, 4, 5];

// map
const doubled = numbers.map(num => num * 2);
console.log(doubled); // [2, 4, 6, 8, 10]

// filter
const evens = numbers.filter(num => num % 2 === 0);
console.log(evens); // [2, 4]

// reduce
const sum = numbers.reduce((acc, num) => acc + num, 0);
console.log(sum); // 15

Explanation: map transforms, filter selects, reduce accumulates.

Web Components

Q: What are “Web Components” in JavaScript, and how do they enhance code reusability
and encapsulation in web development?

Web Components: Reusable custom elements with encapsulated functionality.

Example:

javascript
Copy code
class MyComponent extends HTMLElement {
constructor() {
super();
const shadow = this.attachShadow({ mode: 'open' });
shadow.innerHTML = '<p>Hello World</p>';
}
}
customElements.define('my-component', MyComponent);

document.body.appendChild(new MyComponent());

Explanation: Web Components create reusable custom elements with encapsulated styles and
behavior.

Memoization and Caching

Q: Explain the concepts of “memoization” and “caching” in JavaScript and how they are
used to optimize function performance.

Memoization: Caches function results to avoid redundant calculations. Caching: Stores


frequently accessed data for quick retrieval.

Example:

javascript
Copy code
function memoize(fn) {
const cache = {};
return function(...args) {
const key = JSON.stringify(args);
if (cache[key]) {
return cache[key];
}
const result = fn(...args);
cache[key] = result;
return result;
};
}

const factorial = memoize(function(n) {


if (n === 0) return 1;
return n * factorial(n - 1);
});

console.log(factorial(5)); // 120

Explanation: Memoization caches function results, optimizing performance.

You might also like