例外処理（れいがいしょり、''exception handling''）とは、プログラム実行中に予期せぬ異常が発生した場合に、通常の実行フローを中断し、エラーメッセージの表示や適切な処理を行うプログラムの手法です。
throw文は、プログラムの実行中に発生したエラーや問題を示し、その場で例外を引き起こします。例えば、条件に合致しない場合や予期せぬ状況であれば、throw文を使って例外を発生させることができます。
function reduce(array, callback, initialValue) {
    if (typeof callback != 'function') {
        throw new Error(callback + " is not a function");
    }
    // ...
}
reduce([], null); // "null is not a function" とエラー
後述のtry/catch ブロックなしで throw を実行すると、エラーが現在のコンテキストから伝播し、エラーが発生したポイントからコードの実行が停止されます。これにより、通常の実行フローが中断され、エラーがコンソールに表示されたり、上位の呼び出し元でエラーがキャッチされるまで、エラーが伝播します。
throw文では、あらゆる種類の値を渡すことができますが、通常は例外オブジェクト（Errorなど）を渡します。例外オブジェクトは例外が発生した際の状況を記録し、デバッグを容易にします。特に、ReferenceError、SyntaxError、TypeErrorなどの例外オブジェクトは、エラーのタイプ（参照エラー、構文エラー、型エラーなど）を明確に示すために利用されます。
function reduce( array, callback, initialValue ) {
    if ( typeof callback != 'function' ) {
        throw new TypeError( callback + " is not a function" );
    }
    // ...
}
reduce( [], null ); // "TypeError: null is not a function" とエラー
throw文で例外が投げられると、以降のプログラムの実行は中断され、処理系のエラーコンソールにエラーが表示されます。
try文のブロックの中で例外が発生すると、catch節のブロックが実行され、例外が捕捉されます。try文のブロックで例外が発生しなかった場合は、catch節のブロックは実行されません。catch節のブロックが実行された後も、catch節のブロックの中で例外が発生しなければ、プログラムは中断せずに以降の処理を継続します。
try {
    throw new Error( "エラー!" );
}
catch (e) {
    console.log(e.message); // "エラー!" と表示
}
console.log("しかし処理は続行…");
catch節は複数置くことができます。また、catch節は必ずthrow文のパラメータ''e''を受け取らなければなりません。''e''の変数名は任意の識別子。
finally節は事後処理を行います。catch節の後にfinally節を書くと、例外が発生してもしなくてもfinally節が実行されます。
try {
    console.log("try");     // 0. "try" と表示
}
catch (e) {
    console.log("catch");
}
finally {
    console.log("finally"); // 1. "finally" と表示
}
console.log("outside");     // 2. "outside" と表示
例外が発生した場合は、catch節が実行された後にfinally節が実行されます。finally節が実行された後は以降の処理を継続します。
try {
    console.log("try");     // 0. "try" と表示
    throw new Error();
}
catch (e) {
    console.log("catch");   // 1. "catch" と表示
}
finally {
    console.log("finally"); // 2. "finally" と表示
}
console.log("outside");     // 3. "outside" と表示
try文の後にはcatch節またはfinally節のいずれか、もしくは両方を置かなければなりません。catch節を除いたtry-finally節では、例外が発生してもしなくてもfinally節は実行されますが、catch節によって例外が捕捉されないので、例外が発生した場合は以降の処理を中断します。
[https://paiza.io/projects/NmoKJECDSL3JI1WMdO3a5Q?language=javascript return と finally] :
function div(n, d) {
    try {
        return n / d
    } catch (e) {
        console.log(e)
    } finally {
        console.log(`div(${n}, ${d}) -- finally`)
    }
}
console.log(`div(1, 2) = ${div(1, 2)}`)
console.log(`div(1, 0) = ${div(1, 0)}`)
console.log(`div(0, 0) = ${div(0, 0)}`)
実行結果:
div(1, 2) -- finally
div(1, 2) = 0.5
div(1, 0) -- finally
div(1, 0) = Infinity
div(0, 0) -- finally
div(0, 0) = NaN
try文にfinally節を持つ言語では「tryブロックで例外を出さずのreturn文に達したとき、finally節を実行するか？」が問題になります。
ES/JSでは、return文に達してもfinally節が実行されます。
例外は大域脱出に使うこともできます。大域脱出とは、入れ子になった制御構造の内側から外側に制御を戻すことです。ラベルを伴わないbreakやreturnは最内側の制御構造(for/while/switchと関数)を抜け出すだけですが、例外をthrowすると文や関数を超えて制御が移ります。
この性質を利用すると二重以上のループや関数を脱出することができるのです。
しかし、大域脱出目的の例外の使用には慎重になってください。breakやreturnをラベルと共に使用することで、ほとんどの場合は例外を使うことなく大域脱出を達成できます。
イテレーションメソッドからの脱出
Array.prototype.forEach メソッドの様にcallbackの反復処理を行うイテレーションはbreakやreturnでは脱出ができないので、例外による大域脱出が適用なケースです。
この場合も、for文に置換えるほうが可読性は向上するでしょう。
関数外のラベルにはbreakできません（動かない例）:
const ary = new Array(10).fill(0).map((_, i) => i)
LABEL:
    ary.forEach(function(x) {
        if (x > 5)
            break LABEL; // SyntaxError: Undefined label 'LABEL'
        console.log(x)
    })
[https://paiza.io/projects/0HdEI0i8b0OJNy-HToq1Ig?language=javascript 例外を使ったイテレーションメソッドからの脱出]:
const ary = new Array(10).fill(0).map((_, i) => i);
try {
	ary.forEach(function(x) {
		if (x > 5) {
			throw new Error(`x = ${x}`);
		}
		console.log(x)
	});
} catch {}
実行結果:
0
1
2
3
4
5
[https://paiza.io/projects/UEkdNTXcxK-a6b5TFrNaTA?language=javascript Array.prototype.every() を使ったイテレーションの中断]:
const ary = new Array(10).fill(0).map((_, i) => i);
ary.every(function(x) {
	if (x > 5) {
		return false
	}
	console.log(x)
	return true
});
実行結果:
0
1
2
3
4
5