JavaScript Flashcards

(21 cards)

1
Q

What are the differences between let, var, and const?

A

var is function-scoped and hoisted (initializes as undefined). let is block-scoped and hoisted but in the temporal dead zone (throws ReferenceError if accessed early). const is block-scoped, can’t be reassigned, but object contents can still be mutated. Modern best practice: default to const, use let when reassignment is needed, avoid var.

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

What is hoisting in JavaScript?

A

Hoisting is JavaScript’s behavior of moving declarations to the top of their scope before execution. var declarations are hoisted and initialized as undefined. Function declarations are fully hoisted. let and const are hoisted but placed in the temporal dead zone — accessing them before declaration throws a ReferenceError.

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

What is a closure?

A

A closure is when an inner function retains access to variables from its outer (enclosing) function’s scope, even after the outer function has finished executing. This is used for data encapsulation, factory functions, and callbacks. Example: a counter function that returns an increment function — the inner function ‘closes over’ the count variable.

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

What is the difference between == and ===?

A

== is loose equality — it performs type coercion before comparing. So ‘5’ == 5 is true. === is strict equality — no coercion, both value and type must match. ‘5’ === 5 is false. Always prefer === to avoid unexpected bugs from implicit type conversion.

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

What is the event loop?

A

The event loop is what allows JavaScript (single-threaded) to handle asynchronous operations. The call stack runs synchronous code. When async tasks (like setTimeout or fetch) complete, their callbacks go into the task queue (or microtask queue for Promises). The event loop picks from the queue when the call stack is empty. Microtasks (Promises) are prioritized over macro-tasks (setTimeout).

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

What is the difference between null and undefined?

A

undefined means a variable has been declared but not assigned a value — it’s the default. null is an intentional assignment meaning ‘no value’. typeof undefined is ‘undefined’, while typeof null is ‘object’ (a historical JavaScript bug). Use null explicitly when you want to represent an empty value.

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

What is a Promise?

A

A Promise is an object representing the eventual completion or failure of an asynchronous operation. It has three states: pending, fulfilled, or rejected. You handle results with .then() for success and .catch() for errors. Promises avoid deeply nested callbacks (callback hell) and can be chained. Promise.all() runs multiple promises in parallel.

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

What is async/await?

A

async/await is syntactic sugar over Promises that makes asynchronous code look synchronous. A function marked async always returns a Promise. Inside it, await pauses execution until the Promise resolves. Error handling is done with try/catch blocks instead of .catch(). It makes code more readable but behaves identically to Promises under the hood.

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

What is the difference between call, apply, and bind?

A

All three set the value of ‘this’ explicitly. call invokes the function immediately with arguments passed individually: fn.call(ctx, a, b). apply invokes immediately with arguments as an array: fn.apply(ctx, [a, b]). bind doesn’t invoke immediately — it returns a new function with ‘this’ permanently bound: const bound = fn.bind(ctx).

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

What is prototype inheritance?

A

Every JavaScript object has a prototype — a reference to another object it inherits properties and methods from. When you access a property, JS looks on the object first, then walks up the prototype chain. Classes in modern JS use prototypes under the hood. Object.create() lets you set a prototype explicitly. This is different from classical class-based inheritance in Java or C++.

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

What is the difference between a function declaration and a function expression?

A

A function declaration (function foo() {}) is fully hoisted — you can call it before it appears in the code. A function expression (const foo = function() {}) is not hoisted — the variable is hoisted but the function isn’t assigned until that line runs. Arrow functions are always expressions, never declarations.

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

What are arrow functions and how do they differ from regular functions?

A

Arrow functions (=>) are a shorter syntax for functions. Key difference: they don’t have their own ‘this’ — they inherit ‘this’ from the surrounding lexical context. They also can’t be used as constructors, don’t have ‘arguments’ object, and can’t be generator functions. Ideal for callbacks and when you want to preserve outer ‘this’.

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

What is ‘this’ in JavaScript?

A

this refers to the execution context of a function. In a method, it’s the object the method belongs to. In a regular function (non-strict mode), it’s the global object (window in browsers). In strict mode, it’s undefined. Arrow functions inherit ‘this’ from their lexical scope. In event handlers, it’s typically the element that triggered the event.

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

What is event delegation?

A

Event delegation is attaching a single event listener to a parent element instead of multiple listeners on each child. When an event fires on a child, it bubbles up to the parent. You use event.target to determine which child triggered it. This is more memory-efficient and automatically works for dynamically added children.

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

What is the difference between event.preventDefault() and event.stopPropagation()?

A

preventDefault() stops the default browser behavior (e.g., stops a form from submitting or a link from navigating). stopPropagation() stops the event from bubbling up to parent elements. stopImmediatePropagation() additionally prevents other listeners on the same element from firing.

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

What is a higher-order function?

A

A higher-order function is a function that either takes a function as an argument or returns a function. Built-in examples: map, filter, reduce, forEach. They’re a core pattern in functional programming and enable cleaner, more composable code. Callbacks are a common use case.

17
Q

What is the difference between map, filter, and reduce?

A

map transforms each element and returns a new array of the same length. filter returns a new array of only the elements that pass a condition. reduce accumulates elements into a single value (sum, object, etc.) using a callback and an initial value. All three are pure array methods that don’t mutate the original.

18
Q

What is destructuring in JavaScript?

A

Destructuring lets you unpack values from arrays or properties from objects into variables. Array: const [a, b] = [1, 2]. Object: const { name, age } = person. You can set defaults, rename variables, and use rest syntax. It’s commonly used in function parameters to extract props or options cleanly.

19
Q

What is the spread operator vs rest parameters?

A

Both use ‘…’ but in opposite directions. Spread expands an iterable into individual elements: Math.max(…arr) or […arr1, …arr2]. Rest collects remaining arguments into an array in a function signature: function sum(…nums). Rest must be last in the parameter list.

20
Q

What is a generator function?

A

A generator function (function*) returns a generator object that can pause and resume execution using yield. Each call to .next() runs until the next yield, returning { value, done }. Useful for lazy evaluation, infinite sequences, and implementing async flows. async/await is actually built on generators and Promises internally.