Skip to main content
Code Review

Return to Revisions

2 of 2
added 1 character in body

Getting the length of a string

You split the string into characters and then you count the array's length. While this works, there's an even simpler way of doing it, using the length property of a String:

const length = msgDiv.value.length;

Changing getStrLen

You can cache the DOM elements. Then you don't need to re-query them, each time the function is called:

const strlenInput = document.getElementById('textbox1');
const strlenDisplay = document.getElementById('msg');
const getStrLen = () => {
 strlenDisplay.textContent = strlenInput.value.length;
}

Now this alone won't work in the head-element of your document, as both elements are not available yet. You can either:

  • wait until the DOM is ready to run that script, like document.addEventListener('DOMContentLoaded', function(event) { [...] }, or
  • place the Javascript at the end of your page instead

This is explained in detail here: $(document).ready(function(){}); vs script at the bottom of page.

Creating the Fibonacci sequence

genFibonacci() takes one parameter, so you pass an unused parameter, when calling the function recursively:

genFibonacci(times - 1, false);

There's a flaw in your logic: You don't reset the values each time the button is clicked. If the user's input is 1 and they hit the generate button 5 times, the result is not 0 but:

 0 1 1 2 3

With this in mind, let's try to change your algorithm, that it won't rely on external variables. We also don't necessarily need recursion here:

const getFibonacciValues = (n) => {
 const values = [];
 if (n >= 1) {
 values.push(0);
 }
 
 if (n >= 2) {
 values.push(1);
 }
 for (let i = 2; i < n; ++i) {
 values.push(values[i - 2] + values[i -1]);
 }
 return values;
}

Now we have a function, which purpose is solely to create the values. It doesn't have a clue, how you're going to output them. outFib() is doing this for us now:

const outFib = () => {
 const n = fibInput.value;
 const values = getFibonacciValues(n);
 fibDisplay.textContent = values.join(', ');
}

Now, this still has flaws, so we add a little bit of validation at least:

  • use parseInt to parse the value
  • check whether the input is at least 1
  • check whether the input is a number

The final result could look like this:

const fibButton = document.getElementById('fibClick');
const fibInput = document.getElementById('fibText');
const fibDisplay = document.getElementById('fibseq');
const getFibonacciValues = (n) => {
 const values = [];
 if (n >= 1) {
 values.push(0);
 }
 
 if (n >= 2) {
 values.push(1);
 }
 
 for (let i = 2; i < n; ++i) {
 values.push(values[i - 2] + values[i -1]);
 }
 return values;
};
const outFib = () => {
 const n = parseInt(fibInput.value);
 if (n < 1 || isNaN(n)) {
 fibDisplay.textContent = 'Please insert a number greater than 0';
 return;
 }
 
 const values = getFibonacciValues(n);
 fibDisplay.textContent = values.join(', ');
};
fibClick.addEventListener('click', outFib);
<input type="text" id="fibText">
<button id="fibClick">Generate Fibonacci Sequence</button>
<div id="fibseq"></div>

Further improvements

This will fail for large inputs – try 2000 for example. You'll get a lot of Infinity.

You can take a look into bigNumber.js or you can set an upper limit, like if (n > 1000) { fibDisplay.textContent = 'Too large'; return; } or you could store all values for your maximum n.


Calculating all numbers over and over again is some overhead you could avoid. You could cache already calculated values, and only add new values if n > values.length. Alternatively you can store all numbers beforehand, which is an increase in memory usage, but your runtime becomes incredibly fast, as all you have left is:

const values = [0, 1, 1, 2, 3, ...];
const output = values.splice(0, n);
default

AltStyle によって変換されたページ (->オリジナル) /