The Code

                    
                        function getValues() {
                            let userString = document.getElementById('userString').value;
                            let reversedString = reverseWithRecursion(userString);
                            displayString(reversedString);
                        }
                        
                        function reverseWithRecursion(userString, reversedString = '') {
                            return userString.length == reversedString.length ? reversedString : reverseWithRecursion(userString, userString[reversedString.length] + reversedString);
                        }
                        
                        function basicReverseString(userString) {
                            let reversedString = '';
                            for (let i = userString.length - 1; i >= 0; i--) reversedString += userString[i];
                            return reversedString;
                        }
                        
                        function reverseWithCharAt(userString) {
                            let reversedString = '';
                            for (let i = userString.length - 1; i >= 0; i--) reversedString += userString.charAt(i);
                            return reversedString;
                        }
                        
                        function reverseWithArray(userString) {
                            let userArray = userString.split('');
                            let reversedArray = [];
                            let reversedString = '';
                            for (let i = 0; i < userArray.length; i++) reversedArray.unshift(userArray[i]);
                            for (let i = 0; i < reversedArray.length; i++) reversedString += reversedArray[i];
                            return reversedString;
                        }
                        
                        function displayString(reversedString) {
                            document.getElementById('results').textContent = reversedString;
                            document.getElementById('alert').classList.remove('invisible')
                        }
                    
                

The code is structured in three functions, but I've provided alternative solutions of the middle function. Let's dive in.

getValues()

This function uses no parameters and is designed to retrieve the user's string and control the flow of the overall applet. It begins by retrieving the provided user string and assigning it to userString. It calls reverseWithRecursion(), using userString as an argument and assigning the returned value to reversedString. Finally, the function calls displayString(), using reversedString as an argument.

reverseWithRecursion()

The meat of the applet, this function is recursive and uses userString as a parameter and a blank string, reversedString, as a default parameter. Because reversedString initially has a length of 0 but will steadily increase as we build it up with letters from userString, we can use reversedString as an index to guide the function's recursion.

The function begins by checking if userString and reversedString have the same length. If they do (the end condition of the recursion), then it returns reversedString. Otherwise, it calls itself recursively, passing userString as the first argument, but it's the second argument it passes that's key to how the function's recursion works. The second argument the function passes when calling itself recursively is the letter located in userString at the index of reversedString's length plus reversedString.

To see what this all looks like in action, let's presume userString's value is 'bye':

  • The function first checks if reversedString's length (currently 0) is equal to userString's length (3). It isn't, so the function calls itself. The first argument is 'bye', and the second argument is 'b' because the letter in userString at the index of reversedString's length (again, currently 0) is 'b'.
  • The recursively called function checks if reversedString's length (currently 1) is equal to userString's length (3). It isn't, so the function calls itself. The first argument is 'bye', the same as before. The second argument is 'yb' because the letter in userString at the index of reversedString's length (again, currently 1) is 'y', and the second argument is that letter plus reversedString (currently 'b').
  • The next instance of the recursive function performs the length checks again (2 is not 3), and calls itself once again, passing 'bye' and 'eyb'. The next (and final) instance of the recursion performs the length checks one last time and finds the lengths are equal (3 == 3). Because this is the case, it returns 'eyb', which is passed up through the chain until finally being passed back to the original getValues() function.

Alternatives to reverseWithRecursion()

A string can be reversed without recursion by using for-loops. Alternative solutions that use for-loops have been provided: basicReverseString(), reverseWithCharAt(), and reverseWithArray(). To use any of these solutions, getValues() must be changed to call the desired function instead (the same argument is used for all solutions).

displayString()

This function uses reversedString as a parameter and is designed to display reversedString on the applet page as part of a success message the function reveals. It begins by retrieving the HTML element 'results' and changing its text content with DOM manipulation to match reversedString. It then retrieves the HTML element 'alert', calls its list of classes, and removes the cass 'invisible', which has been keeping the success message hidden.