JS Flashcards

(20 cards)

1
Q

Higher-Order Functions

A

A Higher-Order Function (HOF) is a function that:
✅ Takes another function as an argument, OR
✅ Returns a function as its result

Ex 1:

function multiplyBy(factor) {
return function (num) {
return num * factor;
};
}

const double = multiplyBy(2);
const triple = multiplyBy(3);

console.log(double(5)); // Output: 10

Ex2:

function myForEach(arr, callback) {
for (let i = 0; i < arr.length; i++) {
callback(arr[i], i);
}
}

myForEach([1, 2, 3], (num, index) => {
console.log(Index ${index}: ${num});
});

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
2
Q

Polyfill

A

A polyfill is a piece of JavaScript code that adds missing features to older browsers that don’t support them. It acts as a fallback, allowing developers to use modern features without breaking functionality in unsupported environments.

if (!Array.prototype.reduce) {
Array.prototype.reduce = function (callback, initialValue) {}
}

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
3
Q

new Map() vs {} in js

A

Both Map and Objects ({}) store key-value pairs, but they have key differences:

Key Types: Map allows any type as a key, while objects only allow strings or symbols.
Order Preservation: Map maintains the insertion order, while objects do not guarantee it.
Performance: Map is faster for frequent additions and deletions.
Size Checking: Map has a built-in .size property, whereas objects require Object.keys(obj).length.
Methods: Map has built-in methods like .set(), .get(), .delete(), and .has(), while objects require manual handling.
Prototypes: Map does not inherit from Object.prototype, avoiding potential conflicts.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
4
Q

diff in map
vs
map.hasOwnProperty(diff)
vs
map[diff] != undefined

A

diff in map
js
Copy code
if (diff in map) {
// Key exists in the object
}
✅ Best Choice (Most reliable for objects)

Checks whether diff is a property of map, including inherited properties.
Works even if the value stored is undefined.
Slightly faster than hasOwnProperty().

map.hasOwnProperty(diff)
js
Copy code
if (map.hasOwnProperty(diff)) {
// Key exists in the object
}
✅ Safe and Explicit (Best when avoiding inherited properties)

Ensures that diff is an own property (not inherited).
More readable for people familiar with JavaScript.
Slightly slower than in, but safer in edge cases

map[diff] !== undefined
js
Copy code
if (map[diff] !== undefined) {
// Key exists in the object
}
⚠ Not Always Reliable (Fails when the stored value is undefined)

Directly checks if the value is not undefined.
Fails if the key exists but holds undefined as a value.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
5
Q

sort in js

A

If you call .sort() without a comparator function, JavaScript converts elements to strings and sorts them lexicographically

Accending order
numbers.sort((a, b) => a - b);
Descending order
numbers.sort((a, b) => b- a);

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
6
Q

Explain hoisting in JavaScript.

A

Hoisting is a behavior in JavaScript where variable and function declarations are moved (“hoisted”) to the top of their scope before the code is executed. However, only the declarations are hoisted, not the initializations.

Variables declared with var are hoisted but initialized as undefined.

Variables declared with let and const are hoisted but not initialized. Accessing them before declaration causes a ReferenceError due to the “Temporal Dead Zone” (TDZ).

Function declarations are fully hoisted and can be used before they are defined.

Hoisting with Function Expressions -
Function expressions (both regular and arrow functions) are not fully hoisted because they behave like variables.
You cannot call them before their declaration.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
7
Q

Event delegation

A

Event Delegation is a technique in JavaScript where you add an event listener to a parent element instead of individual child elements. This works because events “bubble up” from child to parent (event bubbling).

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
8
Q

What is a Closure in JavaScript

A

A closure is a function that remembers the variables from its outer scope even after the outer function has finished executing.

function createCounter() {
let count = 0;

return function () {
    count++;
    console.log(`Clicked ${count} times`);
}; }

const buttonCounter = createCounter();

document.getElementById(“myButton”).addEventListener(“click”, buttonCounter);

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
9
Q

What is debouncing and throttling? How are they different?

A

Debounce
💡 Ensures a function is executed only after a specified delay has passed since the last event.

Throttling
Ensures a function executes at most once in a fixed time interval, no matter how many times the event is triggered.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
10
Q

What are the differences between == and ===?

A

1️⃣ == (Loose Equality)
✅ Checks only value, not type.
✅ Performs type coercion (automatic type conversion).
✅ Converts operands to a common type before comparison.
1 == “1” : true

2️⃣ === (Strict Equality)
✅ Checks both value and type.
✅ No type coercion (no automatic conversion).
✅ Both value and type must be identical for true.
1 === “1” : false

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
11
Q

What is the difference between var, let, and const?

A

Differ in scope, re-declaration, hoisting, and mutability.
1️⃣ var (Function-scoped)
✅ Function-scoped: Accessible within the function where it is declared.
✅ Can be re-declared within the same scope.
✅ Hoisted with undefined: Moves the declaration to the top but does not initialize it.
✅ Can be updated (reassigned).

it may lead to unintended memory retention, especially in loops.

2️⃣ let (Block-scoped)
✅ Block-scoped: Accessible only within the {} block where it is declared.
✅ Cannot be re-declared in the same scope.
✅ Hoisted but not initialized: Accessing before declaration gives a ReferenceError.
✅ Can be updated (reassigned).

3️⃣ const (Block-scoped, Immutable Reference)
✅ Block-scoped: Like let, it is accessible only within {}.
✅ Cannot be re-declared in the same scope.
✅ Cannot be reassigned (but object properties can be modified).
✅ Hoisted but not initialized (ReferenceError if accessed before declaration).

2️⃣ Memory Efficiency of const, let, and var
Feature var let const
Scope Function-scoped Block-scoped Block-scoped
Reference Change ✅ Allowed ✅ Allowed ❌ Not Allowed
Element Modification ✅ Allowed ✅ Allowed ✅ Allowed
Reassignment Cost High (can cause memory leaks) High Low (most efficient)
Garbage Collection Efficiency Less efficient Less efficient More efficient
🔹 Key Factor: Avoid Unnecessary Reassignments

Reassigning an array (let arr = [1,2,3] → arr = [4,5,6]) creates new heap allocations, increasing memory usage.

const prevents this by keeping the reference fixed, reducing unnecessary memory churn.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
12
Q

What happens when you await a non-Promise value?

A

await converts non promise to promise - internally promise.resolve(non promise val);

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
13
Q

Event loop

A

The Event Loop is a crucial part of JavaScript that enables asynchronous programming while keeping JavaScript single-threaded.

Event Loop - A mechanism that continuously checks the Call Stack and Queues.

It follows this process:

If the Call Stack is empty, it takes the next microtask from the Microtask Queue and executes it.

If there are no microtasks, it takes the next macrotask from the Task Queue.

Call Stack

A LIFO (Last In, First Out) stack where JavaScript keeps track of function execution.

Functions enter (push) the stack when called and exit (pop) when completed.

Web APIs

Asynchronous functions like setTimeout, fetch, and event listeners are handled by the browser’s Web APIs.

These APIs run in the background and notify JavaScript once they are done.

Task Queue (Macrotask Queue)

Stores callbacks from Web APIs, such as:

setTimeout

setInterval

setImmediate (Node.js)

requestAnimationFrame

Microtask Queue (Priority Queue)

Stores high-priority callbacks:

Promises (.then(), catch(), finally())

MutationObserver (DOM changes monitoring)

Microtasks always execute before macrotasks.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
14
Q

Mutation observer

A

MutationObserver is a built-in JavaScript API that watches for changes in the DOM (Document Object Model) and runs a callback function when modifications occur. This is useful for tracking dynamic content updates, detecting element changes, and reacting to DOM mutations efficiently.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
15
Q

WeakSet and WeakMap

A

WeakMap and WeakSet are special versions of Map and Set that have weaker references to objects, allowing automatic garbage collection when the objects are no longer in use.

✅ WeakMap is great for private data, caching, and DOM tracking.

✅ WeakSet is useful for marking objects (e.g., processed items, active elements).

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
16
Q

GC in js

A

JavaScript manages memory automatically using Garbage Collection (GC), meaning developers don’t need to manually allocate or free memory. The garbage collector identifies unused objects and frees up memory to improve performance.

Algorithms
1. Mark and Sweep
Starts from “roots” (e.g., global variables, local function variables).
2️⃣ Marks all reachable objects.
3️⃣ Unmarked objects (unreachable) are deleted (swept away).
4️⃣ Memory is freed and reused.

  1. Reference counting - Objects are freed when no references exist.

Problem: Circular references (objects referring to each other) prevent GC.

17
Q

Currying

A

Currying transforms a function that takes multiple arguments into a series of functions that take one argument each. Each function returns another function, except the last one, which returns the result.

const curriedFunction = (arg1) => {
return (arg2) => {
return (arg3) => {
return arg1 + arg2 + arg3;
};
};
};

It allows partial application of arguments and enables reusable, specialized functions.

Currying is commonly used in functional programming and provides a clean, modular approach to function design.

18
Q

sort array in js

A

const numbers = [40, 10, 200, 5, 1];
numbers.sort((a, b) => a - b);
console.log(numbers); // Output: [1, 5, 10, 40, 200] (Sorted numerically ascending)

19
Q

sort map by key in js

A

const myMap = new Map([
[‘c’, 30],
[‘a’, 10],
[‘b’, 20],
[‘d’, 40]
]);

console.log(“Original Map (insertion order):”);
console.log(myMap); // Output: Map(4) {“c” => 30, “a” => 10, “b” => 20, “d” => 40}

// 1. Get entries as an array
const entries = Array.from(myMap.entries());
// Or using spread syntax: const entries = […myMap.entries()];

// 2. Sort the array of entries by key (the first element of each entry array)
entries.sort((entryA, entryB) => {
const keyA = entryA[0]; // Get the key of the first entry
const keyB = entryB[0]; // Get the key of the second entry

if (keyA < keyB) {
return -1; // keyA should come before keyB
}
if (keyA > keyB) {
return 1; // keyA should come after keyB
}
return 0; // keys are equal
});

console.log(“\nEntries sorted by key:”);
console.log(entries); // Output: [[“a”, 10], [“b”, 20], [“c”, 30], [“d”, 40]]

// 3. Optional: Create a new Map from the sorted entries
const sortedMapByKey = new Map(entries);
console.log(“\nNew Map created from sorted entries (sorted by key):”);
console.log(sortedMapByKey); // Output: Map(4) {“a” => 10, “b” => 20, “c” => 30, “d” => 40}

20
Q

sort map by value in js

A

const myMap = new Map([
[‘c’, 30],
[‘a’, 10],
[‘b’, 20],
[‘d’, 40]
]);

console.log(“Original Map (insertion order):”);
console.log(myMap); // Output: Map(4) {“c” => 30, “a” => 10, “b” => 20, “d” => 40}

// 1. Get entries as an array
const entries = Array.from(myMap.entries());
// Or using spread syntax: const entries = […myMap.entries()];

// 2. Sort the array of entries by value (the second element of each entry array)
entries.sort((entryA, entryB) => {
const valueA = entryA[1]; // Get the value of the first entry
const valueB = entryB[1]; // Get the value of the second entry

// For numerical sorting of values:
return valueA - valueB;

// For string sorting of values:
// if (valueA < valueB) return -1;
// if (valueA > valueB) return 1;
// return 0;
});

console.log(“\nEntries sorted by value:”);
console.log(entries); // Output: [[“a”, 10], [“b”, 20], [“c”, 30], [“d”, 40]]

// 3. Optional: Create a new Map from the sorted entries
const sortedMapByValue = new Map(entries);
console.log(“\nNew Map created from sorted entries (sorted by value):”);
console.log(sortedMapByValue); // Output: Map(4) {“a” => 10, “b” => 20, “c” => 30, “d” => 40}