A practical JavaScript review guide for technical interviews and front-end development. It covers core language concepts, DOM manipulation, asynchronous programming, debugging, modern JavaScript, and small coding exercises.
- Core concepts
- Functions and scope
- Objects and arrays
- DOM manipulation
- Asynchronous JavaScript
- Error handling
- Testing and debugging
- Modern JavaScript
- Frameworks and libraries
- Coding challenge
- To-do list examples
JavaScript has seven primitive data types:
undefinednullbooleannumberbigintstringsymbol
var legacyValue = 10;
let mutableValue = 20;
const fixedBinding = 30;varis function-scoped and can be reassigned.letis block-scoped and can be reassigned.constis block-scoped and cannot be reassigned after initialization.
constprevents reassignment of the binding; it does not make an object or array immutable.
function greet(name) {
return `Hello, ${name}!`;
}const greet = function (name) {
return `Hello, ${name}!`;
};Function declarations are hoisted with their bodies. A function expression follows the initialization rules of the variable that stores it and cannot be called before that initialization.
Inner scopes can access variables declared in their outer scopes:
const outerValue = 10;
function showValues() {
const innerValue = 20;
console.log(outerValue);
console.log(innerValue);
}
showValues();
console.log(outerValue);
// console.log(innerValue); // ReferenceErrorconst user = {};
user.name = "Alex";
user["role"] = "Developer";Use dot notation for known property names and bracket notation for dynamic names or keys that are not valid identifiers.
const values = [1, 2, 3, 4];
values.push(5); // Add to the end
values.pop(); // Remove from the end
values.shift(); // Remove from the beginning
values.unshift(1); // Add to the beginningAlso review map, filter, reduce, find, some, every, and includes.
const element = document.querySelector(".my-class");
const form = document.getElementById("signup-form");element.classList.add("is-active");
element.classList.remove("is-active");
element.classList.toggle("is-active");element.addEventListener("click", (event) => {
console.log("Clicked", event.currentTarget);
});
form.addEventListener("submit", (event) => {
event.preventDefault();
// Process the form.
});JavaScript executes synchronous code on the call stack. The runtime schedules asynchronous work and queues callbacks. When the stack is empty, the event loop allows queued work to run. Promise callbacks use the microtask queue, which is processed before the next task queue item.
const request = new Promise((resolve, reject) => {
const succeeded = true;
if (succeeded) {
resolve("Success!");
} else {
reject(new Error("Failure!"));
}
});
request
.then((message) => console.log(message))
.catch((error) => console.error(error));async function loadData() {
try {
const result = await someAsyncFunction();
console.log(result);
} catch (error) {
console.error(error);
}
}An async function always returns a Promise. await pauses that function until the awaited Promise settles without blocking the JavaScript thread.
Use throw to create an error condition and try...catch to handle errors:
function divide(a, b) {
if (b === 0) {
throw new Error("Cannot divide by zero");
}
return a / b;
}
try {
console.log(divide(10, 0));
} catch (error) {
console.error(error.message);
}Useful browser debugging tools include:
console.log,console.table, andconsole.error- The
debuggerstatement - Breakpoints and watch expressions in browser DevTools
- Network, Performance, and Memory panels
Common JavaScript testing tools include Jest, Vitest, Mocha, Chai, Jasmine, Testing Library, Cypress, and Playwright.
const add = (a, b) => a + b;Arrow functions use lexical this and do not have their own arguments object. They are not suitable as constructors.
const name = "Alex";
const message = `Hello, ${name}!`;const person = { name: "Alex", role: "Developer" };
const { name, role } = person;
const coordinates = [12, 24];
const [x, y] = coordinates;Popular front-end choices include React, Vue, Svelte, and Angular. Interview discussions may cover:
- Component architecture
- State management
- Props and data flow
- Rendering and lifecycle behavior
- Forms and validation
- Routing
- Testing
- Performance and accessibility
The maximum product may come from either:
- The three largest values.
- The two smallest values and the largest value.
function maxProductOfThree(numbers) {
if (numbers.length < 3) {
throw new Error("At least three numbers are required");
}
const sorted = [...numbers].sort((a, b) => a - b);
const last = sorted.length - 1;
return Math.max(
sorted[last] * sorted[last - 1] * sorted[last - 2],
sorted[0] * sorted[1] * sorted[last],
);
}This version copies the input before sorting so the original array is not mutated.
import { useState } from "react";
export default function TodoList() {
const [todos, setTodos] = useState([]);
const [task, setTask] = useState("");
function addTodo() {
const trimmedTask = task.trim();
if (!trimmedTask) return;
setTodos((current) => [
...current,
{ id: crypto.randomUUID(), text: trimmedTask },
]);
setTask("");
}
return (
<div>
<input
type="text"
value={task}
onChange={(event) => setTask(event.target.value)}
/>
<button type="button" onClick={addTodo}>
Add
</button>
<ul>
{todos.map((todo) => (
<li key={todo.id}>{todo.text}</li>
))}
</ul>
</div>
);
}<label for="task">Task</label>
<input type="text" id="task" />
<button type="button" id="add-task">Add</button>
<ul id="todo-list"></ul>
<script>
const input = document.getElementById("task");
const button = document.getElementById("add-task");
const list = document.getElementById("todo-list");
button.addEventListener("click", () => {
const task = input.value.trim();
if (!task) return;
const item = document.createElement("li");
item.textContent = task;
list.appendChild(item);
input.value = "";
input.focus();
});
</script><script>
let todos = [];
let task = "";
function addTodo() {
const trimmedTask = task.trim();
if (!trimmedTask) return;
todos = [
...todos,
{ id: crypto.randomUUID(), text: trimmedTask },
];
task = "";
}
</script>
<label for="task">Task</label>
<input id="task" bind:value={task} />
<button type="button" on:click={addTodo}>Add</button>
<ul>
{#each todos as todo (todo.id)}
<li>{todo.text}</li>
{/each}
</ul>- Explain each concept in your own words.
- Predict code output before running it.
- Practice solving problems without mutating inputs unless required.
- Be ready to discuss trade-offs, edge cases, complexity, and accessibility.
- Build small projects that combine DOM events, state, async data, and error handling.
This cheat sheet is intended for personal learning and interview preparation.