break と continuebreakbreak とラベル: ラベル付き文からの脱出continueif 文 [ES1]if 文の構文switch 文 [ES3]switch 文の最初の例return または break を忘れないでください!default 句による不正な値のチェックwhile ループ [ES1]while ループの例do-while ループ [ES3]for ループ [ES1]for ループの例for-of ループ [ES6]const: for-of vs. forfor-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 と continue2 つの演算子 break と continue は、ループや他の文の内部にいる間にそれらを制御するために使用できます。
breakbreak には、オペランドを持つバージョンとオペランドを持たないバージョンの 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 である文を終了します。
my_label: { // label
if (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:
result = str;
break search_block; // (A)
}
} // for
// Failure:
result = '(Untitled)'; // (B)
} // search_block
return { suffix, result };
// Same as: {suffix: suffix, result: result}
}
assert.deepEqual(
findSuffix(['notes.txt', 'index.html'], '.html'),
{ suffix: '.html', result: 'index.html' }
);
assert.deepEqual(
findSuffix(['notes.txt', 'index.html'], '.mjs'),
{ suffix: '.mjs', result: '(Untitled)' }
);continuecontinue は、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、nullfalse0、NaN0n''他のすべての値は 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';
}
}
assert.equal(dayOfTheWeek(5), 'Friday');return または break を忘れないでください!case 句の最後で、return または break しない限り、実行は次の case 句に続きます。例:
function englishToFrench(english) {
let french;
switch (english) {
case 'hello':
french = 'bonjour';
case 'goodbye':
french = 'au revoir';
}
return french;
}
// The result should be 'bonjour'!
assert.equal(englishToFrench('hello'), 'au revoir');つまり、dayOfTheWeek() の実装は、return を使用したためだけに機能しました。 break を使用することで englishToFrench() を修正できます。
function englishToFrench(english) {
let french;
switch (english) {
case 'hello':
french = 'bonjour';
break;
case 'goodbye':
french = 'au revoir';
break;
}
return french;
}
assert.equal(englishToFrench('hello'), 'bonjour'); // okcase 句の文を省略することができます。これにより、事実上、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;
}
}
assert.equal(isWeekDay('Wednesday'), true);
assert.equal(isWeekDay('Sunday'), false);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);
}
}
assert.throws(
() => isWeekDay('January'),
{message: 'Illegal value: January'}); 練習問題:
switch
exercises/control-flow/number_to_month_test.mjs
exercises/control-flow/is_object_via_switch_test.mjswhile ループ [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 {
input = prompt('Enter text:');
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
// 2for ループを使用して配列の内容をログに記録する方法は次のとおりです。
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. forfor-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'];
arr.propKey = 'property value';
for (const key in arr) {
console.log(key);
}
// Output:
// '0'
// '1'
// '2'
// 'propKey'for-await-ofを使用する必要があります。for-ofを使用する必要があります。配列はイテラブルであることに注意してください。.forEach()を使用できます。forループを使用して配列をループできます。for-inを使用しないでください。 クイズ
クイズアプリをご覧ください。