In the last part, we did some work on comparisons, solving an interesting exercise. Now – we’ll learn more about Closure by solving another fun exercise.
Just to remind you – we picked these exercises up from Kyle Simpson’s You Don’t Know JS book series, and as I already mentioned those books might be the ultimate resource for mastering JavaScript, and I highly recommend everyone to go through all of the books in the series.
Closure Exercise
The range(..)
function takes a number as its first argument, representing the first number in a desired range of numbers. The second argument is also a number representing the end of the desired range (inclusive). If the second argument is omitted, then another function should be returned that expects that argument.
function range(start,end) { // ..TODO.. } range(3,3); // [3] range(3,8); // [3,4,5,6,7,8] range(3,0); // [] var start3 = range(3); var start4 = range(4); start3(3); // [3] start3(8); // [3,4,5,6,7,8] start3(0); // [] start4(6); // [4,5,6]
Try to solve this yourself first.
Analysis of the Problem
First of all let us just remind ourselves what a Closure is. As you might already know (if not, please refer to a more detailed tutorial encompassing closures) a Closure is the combination of a function bundled together (enclosed) with references to its surrounding state. What this means in Layman’s terms is that the inner function has access and can see all the local and functional variables of the other function, because the state of the other function is stored inside the inner even when the outer finishes it’s execution.
Knowing this we might want to write something like this, just to start out function and write some code:
if (!isNaN(start) && !isNaN(end) && start < end) { return createRange(start, end); } function createRange(start, end) { let range = []; for (let i = start; i <= end; i++) { range.push(i); } return range; }
We are checking whether our parameters are numbers and whether the starting number is lower than the ending. If our conditions pass we run the createRange
function which creates an empty array, loops through the values, pushing them all into the new array we created. In the end, we just return that array.
Otherwise, if we omit the second argument we might return another function which can then be used again. In this case, we might write something like this:
if (end == undefined) { return function getEnd(end) { return createRange(start, end); }; }
Combining everything we will have our final solution in the snippet below.
function range(start, end) { if (end == undefined) { return function getEnd(end) { return createRange(start, end); }; } if (!isNaN(start) && !isNaN(end) && start < end) { return createRange(start, end); } return []; function createRange(start, end) { let range = []; for (let i = start; i <= end; i++) { range.push(i); } return range; } }
Final Words
Hope you had fun solving this exercise with me. In the next part, we will solve Prototype related problems.
For more articles please click below, or check the blog.
- Largest Palindrome Product
- Largest Prime Factor
- Even Fibonacci Numbers
- Multiples of 3 or 5
- How to find the missing number in a given integer array of 1 to 100?
- Understanding Javascript prototypes
- Difference between Promise.all() and Promise.race()
- JavaScript generators
- Using this and arguments
- Arrow functions in JavaScript