午後1時、ベイシアに買い出しに行く
3/20(水)春分、ショート;久下さん家:二日目
午後7時、世界まる見え
午後10時、報道ステーション
午後11時、寝る
3/26(火)入院3日目
午後8時、大河ドラマ
try{ 例外が発生する可能性がある文を記述 ・・・ } catch(e) { 例外をキャッチしたときに実行される処理 ・・・ } finally { 最後に実行される処理 ・・・ }
function sum(a, b){ let sum; try{ sum = a + b; } catch(e) { console.error(e); return null; } finally { console.log('Finally!'); } return sum; } console.log('Start'); console.log(sum(10, 8)); console.log(sum(10, 8n)); console.log('End'); 実行 > Start > Finally! > 18 > TypeError: Cannot mix BigInt and other types, use explicit conversions > Finally! > null > End
try{ 例外が発生する可能性がある文を記述 ・・・ } finally { 最後に実行される処理 ・・・ }
ただ catch がない場合は例外をキャッチすることができませんので、 例外がスローされた場合はプログラムが強制終了します
【開発環境】
OS:Win11(64ビット)
VSCode1.72.2、
クロム
【例外がスローされた時の挙動について】
最初に例外に対して何の処理も記述していないプログラムで例外がスローされた時の挙動を確認しておきます。
サンプル
function sum(a, b){
let sum = a + b;
return sum;
}
console.log('Start');
let result = sum(10, 8);
console.log(result);
console.log('End');
実行
Start
18
End
わざとエラーを起こすようにプログラムを書く
function sum(a, b){ let sum = a + b; return sum; } console.log('Start'); let result = sum(10, 8n); console.log(result); console.log('End');//実行されない 実行 Start TypeError: Cannot mix BigInt and other types, use explicit conversions
【try...catch文の使い方】
try...catch 文を使用するとスローされた例外をキャッチし、行うべき処理について記述することができます。書式は次のとおりです。
try{ 例外が発生する可能性がある文を記述 ・・・ } catch(e) { 例外をキャッチしたときに実行される処理 ・・・ }
サンプル文
function sum(a, b){ let sum; try{ sum = a + b; } catch(e) { //変数eには、例外がスローされたときに設定された値が格納される console.error(e); return null; } return sum; } console.log('Start'); console.log(sum(10, 8)); console.log(sum(10, 8n)); console.log('End'); 実行 > Start > 18 > TypeError: Cannot mix BigInt and other types, use explicit conversions > null > End
関数内の変数を加算する文を try のブロック内に記述します。これでこの文で例外がスローされた場合に例外をキャッチすることができます。
そして catch のブロック内で例外をキャッチした場合に実行される処理を記述しています。
今回はコンソールに対して Error オブジェクトの内容を出力したあと、関数の呼び出し元に対して null を返しています。
コールバック関数/高階関数
関数リテラルを使って関数を定義し、変数 price に格納しています。そのあとで変数に格納した関数を呼びだしています。
サンプル文
//高階関数
//→他の関数を引数として受け取ったり、結果として関数を返す関数の事。
function tomato(price, func){ //関数(値、コールバック関数)
const name = 'トマト';
func(name, price); //コールバック関数を呼び出している
}
//コールバック関数→別の関数に呼び出してもらうための関数
const price = function(name, price){
console.log(name + ' の値段は ' + price + ' 円です。');
} //関数リテラル
tomato(100, price);//呼び出し
実行
トマト の値段は 100 円です。
また
コールバック関数は、引数のところに直接記述することもできる
function tomato(price, func){
const name = 'トマト';
func(name, price);
}
tomato(100, function(name, price){
console.log(name + ' の値段は ' + price + ' 円です。');
});
実行
トマト の値段は 100 円です。
アロー関数式を使ったサンプル
function tomato(price, func){
const name = 'トマト';
func(name, price); //コールバック関数
}
tomato(100, (name, price) => {
console.log(name + ' の値段は ' + price + ' 円です。');
});
実行
トマト の値段は 100 円です。
【コールバック関数が主に使われるケース】
コールバック関数は主に非同期処理を行う時に使用されるもので、呼び出した関数の処理が終わったあとなどにコールバック関数として指定した関数を実行させたい場合に使用されます。
よく例として使われるのが一定時間経過したあとに特定の処理を実行して欲しい場合やボタンがクリックされたときに実行して欲しい処理を指定するためにコールバック関数は使われます。
サンプル
//コールバック関数
const dispBye = function(){
console.log('Bye.');
}
console.log('Good Morning.')
setTimeout(dispBye, 3000); //引数のdispByeはコールバック
console.log('How are you?');
実行
Good Morning.
How are you?
Bye.
setTimeout メソッドは指定された秒数だけ待ったあと、引数に指定されたコールバック関数を実行するメソッドです。
・setTimeout(function, delay);
サンプルを実行すると、 'Good Morning.' と出力したあと setTimeout メソッドを呼び出しています。
3 秒経過するまで待って引数に指定されたコールバック関数が呼び出されますが、非同期のため 3 秒待っている間にも次の処理が順に実行されていきますので 'How are you?' が先に出力されます。
setTimeout メソッドが呼ばれて 3 秒後にコールバック関数が呼ばれて 'Bye.' が実行されます。
再帰関数
function test(){ test(); } test();
関数 test は関数内で自分自身である test 関数を呼びだしています。このように関数内で自分自身の関数を呼びだす関数のことを再帰関数といいます。
サンプル
function test(n){
console.log('Hello');
if (n != 0) {
test(n - 1);
}
console.log('Bye');
}
test(2);
実行
Hello
Hello
Hello
Bye
Bye
Bye
説明
1) test 関数(1)が呼び出される。引数として 2 が渡される。
2) Hello が出力される
3) test 関数(1)内の条件式は 2 != 0 となり true となる
4) test 関数(2)が呼び出される。引数として 1 が渡される
5) Hello が出力される
6) test 関数(2)内の条件式は 1 != 0 となり true となる
7) test 関数(3)が呼び出される。引数として 0 が渡される
8) Hello が出力される
9) test 関数(3)内の条件式は 0 != 0 となり false となる
10) Bye が出力される
11) test 関数(3) が終了する
12) Bye が出力される
13) test 関数(2) が終了する
14) Bye が出力される
15) test 関数(1) が終了する
16) 最初に関数を呼びだした次の処理へ移る
結果としてコンソールには Hello が 3 回 Bye が 3 回出力されます。このように関数が再帰的に呼び出されるたびに条件式が変化していき、最終的に再帰的に関数を呼びださなくなります。
最後の関数呼び出しが終了すると、その関数呼び出しを行った次の処理へ進み、結果的に順番に関数の呼び出しが終了していきます。最後に一番最初に呼び出された関数の呼び出しが終了し、関数を呼びだした次の処理へ移ります。
【再帰関数の具体的な利用方法】
再帰関数は簡単な階乗の計算などから複雑なアルゴリズムの解決方法まで幅広い利用がされていますが、今回は階乗の計算を例に愚弟的な利用方法についてみていきます。
サンプル
fuction calc(n){
if (n == 0){
return 1;
}
return n * calc(n - 1);
}
console.log(calc(5));実行
120
5 の階乗を計算すると 5 * 4 * 3 * 2 * 1 = 120 を求めるものです
1) 関数の戻り値として 5 * calc(4) を計算するため calc(4) が呼び出される 2) calc(4) が呼び出され 4 * calc(3) を計算するため calc(3) が呼び出される 3) calc(3) が呼び出され 3 * calc(2) を計算するため calc(2) が呼び出される 4) calc(2) が呼び出され 2 * calc(1) を計算するため calc(1) が呼び出される 5) calc(1) が呼び出され 1 * calc(0) を計算するため calc(0) が呼び出される 6) calc(0) が呼び出され return 1 が実行される 7) return 1 * 1 が実行される 8) return 2 * 1 * 1 が実行される 9) return 3 * 2 * 1 * 1 が実行される 10) return 4 * 3 * 2 * 1 * 1 が実行される 11) return 5 * 4 * 3 * 2 * 1 * 1 が実行される 12) 120 がコンソールに出力される