10 JavaScript Problems Every Beginner Should Try to Solve
Learning JavaScript becomes much easier once you stop measuring progress by how many tutorials you have watched and start measuring it by what you can actually write.
A beginner can spend hours reading about variables, arrays, functions and loops and still struggle when asked to solve a small programming problem without an example in front of them.
That is normal.
Programming is a skill that develops through repetition. You need to write code, make mistakes, figure out why it failed, and try again. Small problems are particularly useful because they let you practise one idea at a time without the complexity of a complete application.
Here are ten JavaScript problems that beginners can use to build that habit.
- Reverse a string
This is a simple problem, but it teaches an important lesson about working with strings and arrays.
The task is to create a function that receives a string and returns it backwards.
For example:
function reverseString(text) {
// your code here
}
console.log(reverseString("javascript"));
// "tpircsavaj"
One possible solution is:
function reverseString(text) {
return text.split("").reverse().join("");
}
The useful part of this exercise is not memorising split(), reverse() and join().
Try to understand what happens at each step.
The string is converted into an array of characters. The array is reversed. The characters are then joined back together into a string.
Once you understand that sequence, you can start thinking about alternative solutions instead of relying on one pattern.
For example, you could solve the same problem with a loop:
function reverseString(text) {
let result = "";
for (let i = text.length - 1; i >= 0; i--) {
result += text[i];
}
return result;
}
Comparing the two solutions is valuable practice because you begin to see that JavaScript problems can often be solved in several ways.
- Count the vowels in a sentence
The next exercise introduces loops, conditions and strings.
Write a function that counts how many vowels appear in a sentence.
function countVowels(text) {
// your code here
}
console.log(countVowels("JavaScript is useful"));
// 6
A straightforward solution could be:
function countVowels(text) {
let count = 0;
const vowels = "aeiou";
for (const character of text.toLowerCase()) {
if (vowels.includes(character)) {
count++;
}
}
return count;
}
There are several small decisions here.
Why convert the text to lowercase?
Why use includes()?
Why does the counter start at zero?
These questions matter more than simply getting the final answer.
When practising JavaScript, try to explain each line of your solution in your own words. If you cannot explain why a line exists, you probably have another opportunity to learn.
- Find the largest number in an array
Arrays appear everywhere in JavaScript, so beginners should become comfortable processing them.
Consider this array:
const scores = [72, 91, 64, 88, 97, 79];
The task is to find the highest score without using Math.max().
function findLargest(numbers) {
// your code here
}
console.log(findLargest(scores));
// 97
One approach is to keep track of the largest number seen so far.
function findLargest(numbers) {
let largest = numbers[0];
for (const number of numbers) {
if (number > largest) {
largest = number;
}
}
return largest;
}
This is a useful programming pattern.
You start with a value, inspect each item, and update that value when you find something better.
The same basic idea appears in many real applications. You might use it to find the highest score, the most expensive product, the longest message or the latest date.
- Remove duplicate values
Now try something slightly different.
Given an array containing duplicate values:
const numbers = [4, 7, 4, 9, 7, 2, 9, 1];
Return an array containing each value only once.
The expected result is:
[4, 7, 9, 2, 1]
One modern JavaScript solution is:
function removeDuplicates(numbers) {
return [...new Set(numbers)];
}
This is concise, but do not stop there.
Try solving the problem without using Set.
For example:
function removeDuplicates(numbers) {
const result = [];
for (const number of numbers) {
if (!result.includes(number)) {
result.push(number);
}
}
return result;
}
The second version involves more code, but it gives you useful practice with arrays, loops, conditions and includes().
A good exercise does not always have to produce the shortest possible solution.
Sometimes the longer solution teaches you more.
- Count how many times each value appears
This problem introduces a pattern that becomes very useful when working with real data.
Consider:
const fruits = [
"apple",
"banana",
"apple",
"orange",
"banana",
"apple"
];
Create an object that tells you how many times each fruit appears.
The expected result is:
{
apple: 3,
banana: 2,
orange: 1
}
You could solve it like this:
function countItems(items) {
const counts = {};
for (const item of items) {
if (counts[item]) {
counts[item]++;
} else {
counts[item] = 1;
}
}
return counts;
}
This exercise is worth spending time on because it teaches you to transform a list into a useful data structure.
Once you understand this pattern, you will encounter similar problems when processing survey results, product categories, search terms, user actions and many other types of data.
- Filter a list of objects
Real JavaScript applications rarely work with arrays containing only numbers or strings.
You will often work with objects.
For example:
const products = [
{ name: "Keyboard", price: 45 },
{ name: "Mouse", price: 25 },
{ name: "Monitor", price: 180 },
{ name: "Headphones", price: 75 }
];
Write a function that returns only products costing more than 50.
function getExpensiveProducts(products) {
// your code here
}
A simple solution is:
function getExpensiveProducts(products) {
return products.filter(product => product.price > 50);
}
The important concept here is not the syntax alone.
You need to understand that filter() creates a new array containing the items that satisfy the condition.
Try changing the problem.
Return products costing less than 50.
Return products whose names contain a particular letter.
Return products that are currently in stock.
Small changes like these help you move beyond memorising examples and start thinking in terms of conditions and data.
- Transform data with map()
Filtering answers the question, "Which items do I want?"
map() answers a different question, "What should each item become?"
Suppose you have:
const users = [
{ firstName: "Sarah", age: 24 },
{ firstName: "Daniel", age: 31 },
{ firstName: "Maria", age: 27 }
];
Create an array containing only the names.
const names = users.map(user => user.firstName);
console.log(names);
// ["Sarah", "Daniel", "Maria"]
Now make the exercise slightly harder.
Create an array where every user object also contains a label property.
For example:
[
{ firstName: "Sarah", age: 24, label: "Sarah is 24" },
{ firstName: "Daniel", age: 31, label: "Daniel is 31" },
{ firstName: "Maria", age: 27, label: "Maria is 27" }
]
The code might look like:
const updatedUsers = users.map(user => ({
...user,
label: ${user.firstName} is ${user.age}
}));
This is a small but realistic example of transforming application data.
- Calculate a total with reduce()
reduce() can be confusing when you first encounter it.
A simple way to understand it is to think of an accumulator.
Consider:
const prices = [12, 8, 15, 20];
You want the total.
const total = prices.reduce((sum, price) => {
return sum + price;
}, 0);
console.log(total);
// 55
The sum represents the value accumulated so far.
The initial value is 0.
The process is effectively:
0 + 12 = 12
12 + 8 = 20
20 + 15 = 35
35 + 20 = 55
Once that idea makes sense, try something more practical.
Calculate the total cost of products:
const cart = [
{ name: "Book", price: 15 },
{ name: "Notebook", price: 8 },
{ name: "Pen", price: 3 }
];
Your function should return 26.
function calculateTotal(cart) {
return cart.reduce((total, product) => {
return total + product.price;
}, 0);
}
Exercises like this are useful because they connect JavaScript methods to problems you might actually encounter in an application.
- Find the first matching object
Suppose you have a list of users:
const users = [
{ id: 101, name: "Alex" },
{ id: 102, name: "Jordan" },
{ id: 103, name: "Taylor" }
];
Create a function that finds the user with a particular ID.
function findUser(users, id) {
// your code here
}
console.log(findUser(users, 102));
// { id: 102, name: "Jordan" }
The solution can use find():
function findUser(users, id) {
return users.find(user => user.id === id);
}
This is another important distinction to learn.
filter() returns an array.
find() returns the first matching item.
Those differences can look small when you are learning, but choosing the right array method becomes important as your code gets larger.
Try changing the exercise so that the function searches by name instead of ID.
Then make it return null when no user exists.
The more variations you try, the better you understand the underlying concept.
- Build a small DOM interaction
The first nine exercises focus mostly on JavaScript logic.
Eventually, you need to connect that logic to the browser.
Create a button and a counter:
0
Now write JavaScript that increases the number every time the button is clicked.
const button = document.querySelector("#increase");
const countElement = document.querySelector("#count");
let count = 0;
button.addEventListener("click", () => {
count++;
countElement.textContent = count;
});
This small example introduces several ideas at once.
You select elements from the page.
You store application state in a variable.
You listen for an event.
You change the DOM when the event occurs.
Try extending it.
Add a decrease button.
Add a reset button.
Prevent the counter from going below zero.
Display a message when the counter reaches ten.
These changes turn a simple example into a series of increasingly useful exercises.
Do not look at the solution too quickly
One of the biggest mistakes beginners make is checking the answer as soon as they get stuck.
If you immediately copy the solution, you may understand what the code does without developing the ability to produce it yourself.
Instead, try this process.
First, read the problem carefully.
Then write down what the function receives and what it should return.
Next, try a small example by hand.
After that, write your first solution, even if you are not sure it is correct.
Run the code.
Look at the result.
If it fails, identify the exact part that is wrong.
Then make one change at a time.
This process is slower than copying a solution, but it develops a much stronger understanding.
Make your practice slightly harder each time
You do not need to jump from basic exercises directly into a large application.
A better progression is to make small changes to problems you already understand.
For example, if you can find the largest number in an array, try finding the smallest.
Then find both.
Then find the second largest number.
If you can filter products by price, filter them by price and category.
If you can count vowels, count each individual vowel.
If you can build a counter, add a reset button and a maximum value.
This approach keeps the problem familiar while introducing one new challenge.
That is often a better way to learn than constantly switching between unrelated tutorials.
Practice is more useful when you get immediate feedback
When learning alone, one of the hardest parts can be knowing whether your solution is actually correct.
Reading an explanation tells you what the code should do. Writing the code yourself and testing it tells you whether you can make it work.
That is why browser-based JavaScript practice can be useful for beginners. Platforms such as JS Exercises let learners work through JavaScript problems directly in the browser, with exercises, tests and guided lessons rather than requiring a local development setup. The platform currently offers more than 600 exercises alongside its structured learning paths.
For students, JS Exercises also currently offers a year of full access after verification with an eligible academic email, which can make it useful for practising concepts alongside a programming course.
The important point is not which platform you use.
The important point is that you should spend time actually writing code.
Keep a list of problems you could not solve
This is one of the simplest habits you can develop.
Whenever you get stuck on a problem, save it.
Do not only save the solution.
Write down what confused you.
For example:
Problem:
Count how many times each word appears.
What confused me:
I did not know how to create object properties dynamically.
What I learned:
object[word] can be used when the property name comes from a variable.
A month later, try the same problem again without looking at your old solution.
You may be surprised by how much easier it feels.
That is real progress.
You do not need to memorise everything
JavaScript has a large number of methods, APIs and language features.
You do not need to memorise every method before you start building projects.
You need to understand the fundamentals well enough to reason about a problem.
Know how variables work.
Understand conditions and loops.
Be comfortable with functions.
Know how arrays and objects behave.
Understand how to transform and search data.
Learn how events and the DOM work.
Learn how to read errors and debug your code.
Once those foundations are solid, learning new JavaScript features becomes much easier because you have somewhere to place the new information.
Turn exercises into small projects
Exercises are excellent for learning individual concepts, but projects teach you how those concepts work together.
Once you are comfortable with arrays, objects, functions, events and DOM manipulation, build something small.
A habit tracker is a good example.
You could store habits in an array, display them on the page, allow users to add new habits and update their status when they are completed.
A simple decision tool could also work.
Give the user two choices, let them enter a few factors, calculate the results and display a recommendation.
The project does not need to be impressive.
It needs to make you think.
You should have to decide how to structure your data, where to put your functions, how to update the page and what should happen when something goes wrong.
That is where isolated JavaScript knowledge starts becoming programming ability.
Final thoughts
The best way to improve at JavaScript is not to find one perfect tutorial.
It is to create a regular habit of solving problems.
Start with small exercises.
Try to solve them without looking at the answer.
Test your code.
Read the errors.
Change your solution.
Then make the problem slightly harder.
The ten problems in this article cover many of the ideas beginners need to become comfortable with JavaScript, including strings, loops, arrays, objects, array methods, functions and DOM events.
Once these concepts become familiar, move towards larger exercises and small projects. The goal is not to reach a point where you never get stuck.
The goal is to become comfortable with getting stuck, investigating the problem and finding your way to a working solution.
That is one of the most important skills you can develop as a programmer.