Home JavaScript Function Design

Function Structure

If you have a single function that is very long, break it apart into smaller sub-functions. The definition of "very long" is vague, but often a function longer than 20-30 lines is pushing it.

If you try to describe the function's purpose and find yourself using the word "and" a lot, that probably means the function does too many things and should be split into sub-functions.

Boolean Zen

Don't ever test whether a boolean value is == or != to true or false.

if (x == true) {
  ...
} else if (x != true) {
  ...
}
if (x) {
  ...
} else {
  ...
}

If you have an if/else statement that returns a boolean value based on a test, just directly return the test's result instead.

if (score1 === score2) {
  return true;
} else {
  return false;
}
return score1 === score2;

If/Else Usage

If/Else Branching Patterns

When using if/else statements, properly choose between various if and else patterns depending on whether the conditions relate to one another. Avoid redundant or unnecessary if tests.

if (grade >== 90) {
  alert("You got an A!");
}
if (grade >== 80 && grade < 90) {
  alert("You got a B!");
}
if (grade >== 70 && grade < 80) {
  alert("You got a C!");
}
...
if (grade >== 90) {
  alert("You got an A!");
} else if (grade >== 80) {
  alert("You got a B!");
} else if (grade >== 70) {
  alert("You got a C!");
}
...

If/Else Factoring

Move common code out of if/else statements so that it is not repeated (ie., minimize redundancy in your code).

if (x < y) {
  foo();
  x++;
  alert("hi");
} else {
  foo();
  y++;
  alert("hi");
}
foo();
if (x < y) {
  x++;
} else {
  y++;
}
alert("hi");

Loop Usage

For Loops vs. While Loops

Use a for loop when the number of repetitions is known (definite); use a while loop when the number of repetitions is unknown (indefinite).

// repeat exactly size/2 times
for (let i = 0; i < size / 2; i++) {
  ...
}

// repeat until the user clicks OK
while (!confirm("Are you sure?")) {
  ...
}

Break and Continue

In general, you should avoid break, continue, and empty return statements unless absolutely necessary. In this class, you should never use these statements - for the length and complexity of the programs we ask you to write, these statements deviate from clear logical flow and you should instead consider ways to refactor your conditional statements and loops to handle different cases without forced "shortcuts".

One suggestion to find ways to design your logic cleanly is to add inline comments for different cases - this can help identify the meaningful cases to cleanly separate important conditional blocks, while also avoiding redundancy.

Anonymous Functions

Anonymous functions are useful and expressive in some cases where a function's name is meaningless and cumbersome, such as an initial window.onload handler. But over-using anonymous functions leads to code that is too heavily nested and has too few names to guide the programmer, so over-use of anonymous functions should be avoided. In general, give names to your functions unless the name is truly useless and meaningless.

window.addEventListener("load", function() {
  myButton.addEventListener("click", function() {
    setTimeout(function() {
      alert("hi!");
    }, 1000);
  });
  // any other event listener setup you have 
});
window.addEventListener("load", initialize); 

function initialize() {
  myButton.addEventListener("click", myButtonClick);
  // any other event listener setup you have 
}

function myButtonClick() {
  setTimeout(displayMessage, 1000);
}

function displayHiMessage() {
  alert("hi!");
}