5.8 Control structures

5.8.1 For loops

With ES6, the language now has three different kinds of for loops. All may beused, though for-of loops should be preferred when possible.

for-in loops may only be used on dict-style objects (see??), and should not be used to iterate over anarray. Object.prototype.hasOwnProperty should be used in for-in loops toexclude unwanted prototype properties. Prefer for-of and Object.keys overfor-in when possible.

5.8.2 Exceptions

Exceptions are an important part of the language and should be used wheneverexceptional cases occur. Always throw Errors or subclasses of Error: neverthrow string literals or other objects. Always use new when constructing anError.

This treatment extends to Promise rejection values as Promise.reject(obj) isequivalent to throw obj; in async functions.

Custom exceptions provide a great way to convey additional error informationfrom functions. They should be defined and used wherever the native Errortype is insufficient.

Prefer throwing exceptions over ad-hoc error-handling approaches (such aspassing an error container reference type, or returning an object with an errorproperty).

5.8.2.1 Empty catch blocks

It is very rarely correct to do nothing in response to a caught exception. Whenit truly is appropriate to take no action whatsoever in a catch block, thereason this is justified is explained in a comment.

  1. try {
  2. return handleNumericResponse(response);
  3. } catch (ok) {
  4. // it's not numeric; that's fine, just continue
  5. }
  6. return handleTextResponse(response);

Disallowed:

  1. try {
  2. shouldFail();
  3. fail('expected an error');
  4. } catch (expected) {
  5. }

Tip: Unlike in some other languages, patterns like the above simply don’t worksince this will catch the error thrown by fail. Use assertThrows() instead.

5.8.3 Switch statements

Terminology Note: Inside the braces of a switch block are one or more statement groups. Each statement group consists of one or more switch labels (either case FOO: or default:), followed by one or more statements.

5.8.3.1 Fall-through: commented

Within a switch block, each statement group either terminates abruptly (with abreak, return or thrown exception), or is marked with a comment toindicate that execution will or might continue into the next statementgroup. Any comment that communicates the idea of fall-through is sufficient(typically // fall through). This special comment is not required in the laststatement group of the switch block.

Example:

  1. switch (input) {
  2. case 1:
  3. case 2:
  4. prepareOneOrTwo();
  5. // fall through
  6. case 3:
  7. handleOneTwoOrThree();
  8. break;
  9. default:
  10. handleLargeNumber(input);
  11. }
5.8.3.2 The default case is present

Each switch statement includes a default statement group, even if it containsno code. The default statement group must be last.