break
と continue
break
break
とラベル: ラベル付き文からの脱出continue
if
文 [ES1]if
文の構文switch
文 [ES3]switch
文の最初の例return
または break
を忘れないでください!default
句による不正な値のチェックwhile
ループ [ES1]while
ループの例do-while
ループ [ES3]for
ループ [ES1]for
ループの例for-of
ループ [ES6]const
: for-of
vs. for
for-await-of
ループ [ES2018]for-in
ループ (避ける) [ES1]この章では、以下の制御フロー文について説明します。
if
文 [ES1]switch
文 [ES3]while
ループ [ES1]do-while
ループ [ES3]for
ループ [ES1]for-of
ループ [ES6]for-await-of
ループ [ES2018]for-in
ループ [ES1]break
と continue
2 つの演算子 break
と continue
は、ループや他の文の内部にいる間にそれらを制御するために使用できます。
break
break
には、オペランドを持つバージョンとオペランドを持たないバージョンの 2 つがあります。後者のバージョンは、while
、do-while
、for
、for-of
、for-await-of
、for-in
、switch
文の内部で動作します。現在の文をすぐに終了します。
for (const x of ['a', 'b', 'c']) {
console.log(x);
if (x === 'b') break;
console.log('---')
}
// Output:
// 'a'
// '---'
// 'b'
break
とラベル: ラベル付き文からの脱出オペランドを持つ break
は、どこでも動作します。そのオペランドは *ラベル* です。ラベルは、ブロックを含む任意の文の前に置くことができます。 break my_label
は、ラベルが my_label
である文を終了します。
: { // label
my_labelif (condition) break my_label; // labeled break
// ···
}
次の例では、検索は次のいずれかの結果になります。
result
を見つけずに終了します。これは、ループの直後 (行 B) で処理されます。result
が見つかりました。次に、break
とラベル (行 A) を使用して、失敗を処理するコードをスキップします。function findSuffix(stringArray, suffix) {
let result;
search_block: {
for (const str of stringArray) {
if (str.endsWith(suffix)) {
// Success:
= str;
result break search_block; // (A)
}// for
} // Failure:
= '(Untitled)'; // (B)
result // search_block
}
return { suffix, result };
// Same as: {suffix: suffix, result: result}
}.deepEqual(
assertfindSuffix(['notes.txt', 'index.html'], '.html'),
suffix: '.html', result: 'index.html' }
{ ;
).deepEqual(
assertfindSuffix(['notes.txt', 'index.html'], '.mjs'),
suffix: '.mjs', result: '(Untitled)' }
{ ; )
continue
continue
は、while
、do-while
、for
、for-of
、for-await-of
、for-in
の内部でのみ動作します。現在のループの反復処理をすぐに終了し、次の反復処理を続行します。例:
const lines = [
'Normal line',
'# Comment',
'Another normal line',
;
]for (const line of lines) {
if (line.startsWith('#')) continue;
console.log(line);
}// Output:
// 'Normal line'
// 'Another normal line'
if
、while
、do-while
には、原則としてブール値である条件があります。ただし、条件は *truthy* (ブール値に強制変換された場合に true
) であるだけで受け入れられます。つまり、次の 2 つの制御フロー文は同等です。
if (value) {}
if (Boolean(value) === true) {}
これは、すべての *falsy* 値のリストです。
undefined
、null
false
0
、NaN
0n
''
他のすべての値は truthy です。詳細については、§15.2 “Falsy な値と truthy な値” を参照してください。
if
文 [ES1]これらは 2 つの単純な if
文です。「then」分岐のみを持つものと、「then」分岐と「else」分岐の両方を持つものです。
if (cond) {
// then branch
}
if (cond) {
// then branch
else {
} // else branch
}
ブロックの代わりに、else
の後に別の if
文を続けることもできます。
if (cond1) {
// ···
else if (cond2) {
} // ···
}
if (cond1) {
// ···
else if (cond2) {
} // ···
else {
} // ···
}
このチェーンをさらに else if
で続けることができます。
if
文の構文if
文の一般的な構文は次のとおりです。
if (cond) «then_statement»
else «else_statement»
これまでのところ、then_statement
は常にブロックでしたが、任意の文を使用できます。その文はセミコロンで終了する必要があります。
if (true) console.log('Yes'); else console.log('No');
つまり、else if
はそれ自体が構成要素ではなく、単に else_statement
が別の if
文である if
文です。
switch
文 [ES3]switch
文は次のようになります。
switch («switch_expression») {
«switch_body»
}
switch
の本体は、ゼロ個以上の case 句で構成されます。
case «case_expression»:
«statements»
また、オプションで default 句を含めることができます。
default:
«statements»
switch
は次のように実行されます。
switch
文の最初の例例を見てみましょう。次の関数は、1〜7 の数値を曜日の名前に変換します。
function dayOfTheWeek(num) {
switch (num) {
case 1:
return 'Monday';
case 2:
return 'Tuesday';
case 3:
return 'Wednesday';
case 4:
return 'Thursday';
case 5:
return 'Friday';
case 6:
return 'Saturday';
case 7:
return 'Sunday';
}
}.equal(dayOfTheWeek(5), 'Friday'); assert
return
または break
を忘れないでください!case 句の最後で、return
または break
しない限り、実行は次の case 句に続きます。例:
function englishToFrench(english) {
let french;
switch (english) {
case 'hello':
= 'bonjour';
french case 'goodbye':
= 'au revoir';
french
}return french;
}// The result should be 'bonjour'!
.equal(englishToFrench('hello'), 'au revoir'); assert
つまり、dayOfTheWeek()
の実装は、return
を使用したためだけに機能しました。 break
を使用することで englishToFrench()
を修正できます。
function englishToFrench(english) {
let french;
switch (english) {
case 'hello':
= 'bonjour';
french break;
case 'goodbye':
= 'au revoir';
french break;
}return french;
}.equal(englishToFrench('hello'), 'bonjour'); // ok assert
case 句の文を省略することができます。これにより、事実上、case 句ごとに複数の case 式を使用できます。
function isWeekDay(name) {
switch (name) {
case 'Monday':
case 'Tuesday':
case 'Wednesday':
case 'Thursday':
case 'Friday':
return true;
case 'Saturday':
case 'Sunday':
return false;
}
}.equal(isWeekDay('Wednesday'), true);
assert.equal(isWeekDay('Sunday'), false); assert
default
句による不正な値のチェックswitch
式に他の合致がない場合、default
句にジャンプします。これはエラーチェックに役立ちます。
function isWeekDay(name) {
switch (name) {
case 'Monday':
case 'Tuesday':
case 'Wednesday':
case 'Thursday':
case 'Friday':
return true;
case 'Saturday':
case 'Sunday':
return false;
default:
throw new Error('Illegal value: '+name);
}
}.throws(
assert=> isWeekDay('January'),
() message: 'Illegal value: January'}); {
練習問題:
switch
exercises/control-flow/number_to_month_test.mjs
exercises/control-flow/is_object_via_switch_test.mjs
while
ループ [ES1]while
ループの構文は次のとおりです。
while («condition») {
«statements»
}
各ループの反復処理の前に、while
は condition
を評価します。
while
本体はもう一度実行されます。while
ループの例次のコードは while
ループを使用しています。各ループの反復処理で、.shift()
を使用して arr
の最初の要素を削除し、それをログに記録します。
const arr = ['a', 'b', 'c'];
while (arr.length > 0) {
const elem = arr.shift(); // remove first element
console.log(elem);
}// Output:
// 'a'
// 'b'
// 'c'
条件が常に true
と評価される場合、while
は無限ループになります。
while (true) {
if (Math.random() === 0) break;
}
do-while
ループ [ES3]do-while
ループは while
とよく似ていますが、条件を各ループの反復処理の *後* にチェックします (前ではありません)。
let input;
do {
= prompt('Enter text:');
input console.log(input);
while (input !== ':q'); }
do-while
は、少なくとも 1 回は実行される while
ループと見なすこともできます。
prompt()
は、Web ブラウザで使用できるグローバル関数です。ユーザーにテキストの入力を促し、それを返します。
for
ループ [ES1]for
ループの構文は次のとおりです。
for («initialization»; «condition»; «post_iteration») {
«statements»
}
最初の行はループの *ヘッド* で、*本体* (ループの残りの部分) が何回実行されるかを制御します。3 つの部分があり、それぞれがオプションです。
initialization
: ループの変数などを設定します。ここで let
または const
を使用して宣言された変数は、ループ内でのみ存在します。condition
: この条件は、各ループの反復処理の前にチェックされます。falsy の場合、ループは停止します。post_iteration
: このコードは、各ループの反復処理の後に実行されます。したがって、for
ループは、次の while
ループとほぼ同等です。
«initialization»
while («condition») {
«statements»
«post_iteration»
}
for
ループの例例として、for
ループを使用して 0 から 2 までカウントする方法は次のとおりです。
for (let i=0; i<3; i++) {
console.log(i);
}
// Output:
// 0
// 1
// 2
for
ループを使用して配列の内容をログに記録する方法は次のとおりです。
const arr = ['a', 'b', 'c'];
for (let i=0; i<arr.length; i++) {
console.log(arr[i]);
}
// Output:
// 'a'
// 'b'
// 'c'
ヘッドの 3 つの部分をすべて省略すると、無限ループになります。
for (;;) {
if (Math.random() === 0) break;
}
for-of
ループ [ES6]for-of
ループは、任意の *イテラブル* ( 反復プロトコル をサポートするデータコンテナ) を反復処理します。反復処理された各値は、ヘッドで指定された変数に格納されます。
for («iteration_variable» of «iterable») {
«statements»
}
反復変数は通常、変数宣言によって作成されます。
const iterable = ['hello', 'world'];
for (const elem of iterable) {
console.log(elem);
}// Output:
// 'hello'
// 'world'
しかし、既に存在する (変更可能な) 変数を使用することもできます。
const iterable = ['hello', 'world'];
let elem;
for (elem of iterable) {
console.log(elem);
}
const
: for-of
vs. for
for-of
ループでは const
を使用できることに注意してください。反復変数は、反復処理ごとに異なる可能性があります (反復処理中に変更できないだけです)。新しいスコープで毎回新しい const
宣言が実行されると考えてください。
対照的に、for
ループでは、値が変化する場合、変数を let
または var
を使用して宣言する必要があります。
前述のように、for-of
は配列だけでなく、任意のイテラブルオブジェクト (たとえば、Set) で動作します。
const set = new Set(['hello', 'world']);
for (const elem of set) {
console.log(elem);
}
最後に、for-of
を使用して配列の [index, element] エントリを反復処理することもできます。
const arr = ['a', 'b', 'c'];
for (const [index, elem] of arr.entries()) {
console.log(`${index} -> ${elem}`);
}// Output:
// '0 -> a'
// '1 -> b'
// '2 -> c'
[index, element]
を使用すると、 *分割代入* を使用して配列要素にアクセスしています。
**練習問題:
for-of
**
exercises/control-flow/array_to_string_test.mjs
for-await-of
ループ [ES2018]for-await-of
は for-of
に似ていますが、同期イテラブルではなく非同期イテラブルで動作します。また、非同期関数と非同期ジェネレーター内でのみ使用できます。
for await (const item of asyncIterable) {
// ···
}
for-await-of
については、非同期反復処理の章 で詳しく説明しています。
for-in
ループ (避ける) [ES1]for-in
ループは、オブジェクトのすべての(自身および継承された)列挙可能なプロパティキーを走査します。配列をループする場合、これはめったに良い選択ではありません。
以下のコードはこれらの点を示しています。
const arr = ['a', 'b', 'c'];
.propKey = 'property value';
arr
for (const key in arr) {
console.log(key);
}
// Output:
// '0'
// '1'
// '2'
// 'propKey'
for-await-of
を使用する必要があります。for-of
を使用する必要があります。配列はイテラブルであることに注意してください。.forEach()
を使用できます。for
ループを使用して配列をループできます。for-in
を使用しないでください。 クイズ
クイズアプリをご覧ください。