One thing I struggled with when learning JavaScript was knowing what to do when I understood the syntax but could not solve a problem.
I could understand variables, loops, functions and arrays when someone explained them. But when I was given a blank editor and a problem to solve, I often had no idea where to begin.
Over time, I found that the problem was not always JavaScript itself.
I was trying to write the solution before understanding the problem.
Here is the process I now use when I get stuck.
1. Read the problem without writing code
Suppose the problem says:
Write a function that receives an array of numbers and returns the numbers that appear more than once.
My first instinct might be to start writing a loop.
Instead, I stop and create a simple example.
const numbers = [4, 7, 4, 9, 2, 7, 7];
What should the result be?
[4, 7]
Now the problem is much clearer.
I need to identify values that occur more than once.
That is easier to reason about than simply staring at the original question.
2. Work through the example manually
Before writing JavaScript, I try to solve the problem with a pen and paper.
For the array:
[4, 7, 4, 9, 2, 7, 7]
I can count the values:
4 appears 2 times
7 appears 3 times
9 appears 1 time
2 appears 1 time
Now I know that I need some way to keep track of how many times each value appears.
That immediately suggests an object could be useful.
3. Break the problem into smaller tasks
Instead of thinking:
“How do I solve this?”
I ask:
“What are the individual things I need to do?”
In this example:
- Go through every number.
- Keep track of how often each number appears.
- Find the numbers whose count is greater than one.
- Return those numbers.
Now I have a plan.
The code becomes much easier to write because I am no longer trying to solve the entire problem at once.
4. Write the simplest version first
I would start with something like this:
function findDuplicates(numbers) {
const counts = {};
for (const number of numbers) {
if (counts[number]) {
counts[number]++;
} else {
counts[number] = 1;
}
}
const duplicates = [];
for (const number in counts) {
if (counts[number] > 1) {
duplicates.push(Number(number));
}
}
return duplicates;
}
Then test it:
console.log(
findDuplicates([4, 7, 4, 9, 2, 7, 7])
);
The expected result is:
[4, 7]
The solution is not necessarily the shortest or most clever solution.
That is fine.
When learning, I would rather have a solution I understand than a one-line solution I copied from somewhere.
5. Test more than one example
Getting the expected result once does not necessarily mean the function is correct.
I would test several cases.
findDuplicates([1, 2, 3, 4]);
Expected:
[]
Another case:
findDuplicates([5, 5, 5, 5]);
Expected:
[5]
And an empty array:
findDuplicates([]);
Expected:
[]
Testing different inputs forces you to think about edge cases.
This is something I did not pay enough attention to when I first started learning.
I often tested the exact example from the exercise and assumed the function was finished.
6. Use console.log when you are confused
When a solution does not work, I try not to immediately rewrite everything.
Instead, I inspect what the program is doing.
For example:
function findDuplicates(numbers) {
const counts = {};
for (const number of numbers) {
if (counts[number]) {
counts[number]++;
} else {
counts[number] = 1;
}
console.log(number, counts);
}
return counts;
}
The output lets me see how counts changes after every iteration.
This can reveal mistakes that are difficult to spot by simply reading the code.
For beginners, console.log() is more than a way to print a final answer.
It is a debugging tool.
7. Do not change five things at once
This is another habit that helped me.
If something is broken, change one thing and test again.
For example, if this does not work:
if (counts[number] > 1) {
duplicates.push(number);
}
I would inspect counts[number].
Maybe the problem is that the count has not been created correctly.
Maybe the value is a string instead of a number.
Maybe the loop is not processing all the values.
The goal is to find the exact point where my assumption differs from what the program is doing.
8. Learn array methods by solving problems
I used to learn methods such as map(), filter() and reduce() by memorising examples.
That helped with syntax, but it did not help much when I faced a new problem.
A better approach is to start with a requirement.
For example:
const numbers = [3, 8, 12, 5, 20];
Requirement:
“Return only numbers greater than 10.”
I can use:
const result = numbers.filter(number => number > 10);
Then change the requirement:
“Return each number multiplied by two.”
const result = numbers.map(number => number * 2);
Then:
“Calculate the total.”
const result = numbers.reduce(
(total, number) => total + number,
0
);
The important thing is learning to recognise the type of operation you need.
You are not trying to memorise three methods.
You are learning to recognise three different problems.
9. Try the problem again without looking at your old solution
This is probably one of the most useful things I have found.
After solving a problem, wait a day or two and try it again without looking at the solution.
If you can solve it again, you probably understood the concept.
If you cannot, that is useful information too.
It tells you that you may have remembered the solution without fully understanding why it worked.
For example, if you learned how to remove duplicates using Set:
const unique = [...new Set(numbers)];
Try solving the same problem without Set.
That forces you to think about what “unique” actually means and how you would implement it yourself.
10. Make small variations
Once I can solve a problem, I like to change the requirements.
Suppose the original problem is:
“Find the largest number.”
const numbers = [12, 5, 19, 7, 3];
Then I might change it to:
“Find the smallest number.”
Then:
“Find both the largest and smallest.”
Then:
“Find the second largest.”
Then:
“Find the largest number without using Math.max().”
Each variation requires slightly different thinking.
This is where I feel that real programming ability starts developing.
What I do when I completely understand nothing
Sometimes a problem is simply beyond my current level.
In that situation, I do not think there is anything wrong with looking for help.
But I try to look for an explanation rather than immediately copying the final code.
For example, if I do not understand reduce(), I would first learn what an accumulator is and work through a very small example.
Then I would return to the original problem.
The same applies to promises, closures, destructuring, recursion or any other concept that feels unfamiliar.
Understanding the missing concept is usually more useful than memorising the solution to one exercise.
Practice is different from reading
One thing that has become obvious to me is that reading JavaScript code can create a false sense of progress.
I can read this:
const adults = users.filter(user => user.age >= 18);
and understand exactly what it does.
But that does not necessarily mean I can write it from memory when given a problem.
There is a difference between recognising code and producing code.
That is why I think solving small JavaScript exercises is so useful.
You have to start with a blank space and decide what to write.
For anyone who wants a structured place to do that kind of JavaScript practice, there are platforms that provide exercises with immediate feedback. I have found that this type of practice can be useful when you want to spend more time writing code and less time searching for what to practise next.
A simple routine for beginners
If I were starting JavaScript again, I would keep the practice routine simple.
I would spend some time learning one concept.
Then I would solve two or three small problems using it.
After solving them, I would change the requirements and solve them again.
Finally, I would review the mistakes I made.
For example, if I were learning arrays:
Day 1
Find the largest number
Find the smallest number
Day 2
Remove duplicates
Find duplicate values
Day 3
Use filter()
Use map()
Day 4
Use reduce()
Combine multiple array methods
Day 5
Solve the same problems again without looking at the answers
The exact schedule does not matter very much.
What matters is spending time actually writing JavaScript.
You do not need to know everything before building projects
Another mistake I made was thinking I needed to finish learning JavaScript before starting projects.
That point never really arrives.
There is always another method, API, browser feature or language concept to learn.
A small project can actually show you what you need to learn next.
You might start a simple task manager and realise you need to understand DOM events.
Then you discover local storage.
Then you need to work with arrays of objects.
Then you need to handle form validation.
Each problem gives you a reason to learn the next concept.
That is much more practical than trying to learn every JavaScript feature in advance.
Final thought
When I get stuck on a JavaScript problem now, I try not to ask:
“What syntax am I missing?”
I ask:
“What exactly is the problem asking me to do?”
Then I create a small example, solve it manually, break it into smaller steps and write the simplest solution I can.
If it does not work, I debug it.
If it works, I change the requirements and try again.
That process has been much more useful to me than trying to memorise every JavaScript method.
I am curious how other people approach this.
When you get stuck on a JavaScript problem, what is the first thing you usually do?