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 Error
s 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 Error
type 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.
try {
return handleNumericResponse(response);
} catch (ok) {
// it's not numeric; that's fine, just continue
}
return handleTextResponse(response);
Disallowed:
try {
shouldFail();
fail('expected an error');
} catch (expected) {
}
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 throw
n 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:
switch (input) {
case 1:
case 2:
prepareOneOrTwo();
// fall through
case 3:
handleOneTwoOrThree();
break;
default:
handleLargeNumber(input);
}
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.