◆ 特定条件のときに処理した結果を return それ以外は処理を続行する
◆ いっぱいあるし長めの処理を繰り返し書きたくないので関数化
◆ 関数なので結局呼び出し元で if 文で確認して return が必要
◆ 一気に return したい

◆ throw の機能で実装してみた けどオススメはしない

複数の関数で共通の処理で 「もし○○なら特定処理の結果を返してそれ以外ならそのまま次の処理をする」というのが多くありました
よくある簡単な例だと引数が null なら null を返してそれ以外なら続行 でしょうか

これくらいだと 1 行直接書くだけでいいのですが 実際やりたいのはもうちょっと処理が複雑です
同じことを関数ごとには書きたくないので関数にまとめたのですが 関数を呼び出す以上 その関数内から直接 return させられません

関数 A が 関数 B を呼び出していて B の中で 関数 C を呼び出しているときに C から直接 A に戻ることは出来ないですよね
いったん B に戻って B で return することで A にもどります
C の結果を絶対 return するなら B の中で return C() のようにするだけでいいです
しかし C の中でもしこういう条件なら A まで戻る そうでないなら B から処理を続けるといったものです
現実的には B で C の結果を見て return するかそのまま続けるかを判断することになります

でもこれってけっこう面倒でムダに行数が増えるし見づらくなります
理想はこういうコードなんです

function foo(value){
returnIfXXX(value)
returnIfYYY(value)
returnIfZZZ(value)

return convert(value, {
flag1: true,
flag2: false,
})
}

function bar(value){
returnIfXXX(value)
returnIfYYY(value)
returnIfZZZ(value)

return convert2(value, true, false, true)
}

下側の convert 部分が本来のそれぞれの関数でやりたいことです
上にある returnIF*** のところで特定条件の場合は各処理の結果をそのまま return させたいです

それぞれの関数の条件ごと全部に
{
const resultXXX = returnIfXXX(value)
if(resultXXX){
return resultXXX
}
}

なんて書きたいないのです

throw してみる

一気に戻れるといえば throw
ということで誰もが思いつく?こんな方法をやってみました

function main(){
const value1 = useJumpReturn(() => foo({XXX: 1, ZZZ: 3}))
console.log(value1)
const value2 = useJumpReturn(() => foo({YYY: 2, ZZZ: 4}))
console.log(value2)
}
main()

function returnIfXXX(value){
if(value.XXX){
throw {result: value.XXX, jump_return: true}
}
}

function foo(value){
returnIfXXX(value)

return value.YYY * value.ZZZ
}

function useJumpReturn(fn){
try{
return fn()
}catch(err){
if(err.jump_return){
return err.result
}
throw err
}
}
1
8

throw での return 機能を使う部分を useJumpReturn 関数に処理を関数でラップして渡します
useJumpReturn 関数では try 句の中で受け取った関数を実行してそこでエラーを受け取ったら 普通のエラーか jump return 機能かを判断して jump return 機能の場合は普通に返り値として jump return の結果を返します

jump return したいところでは return の代わりに throw で決まったフォーマットの object を返します
result プロパティに結果を jump_return プロパティに true を指定したオブジェクトにしてます

returnIf*** な機能を多用したくなるようなものを作ってるときにはアリかなっと思える便利さです

ちょっと改良

毎回呼び出すために無名関数を渡す方法は面倒なので 呼び出す関数側で useJumpReturn を使うようにしてしまってもうちょっと楽に使えるようにします

function main(){
const value1 = foo({XXX: 1, ZZZ: 3})
console.log(value1)
const value2 = foo({YYY: 2, ZZZ: 4})
console.log(value2)
}
main()

function foo(value){
return useJumpReturn(() => {
returnIfXXX(value)

return value.YYY * value.ZZZ
})
}

とか

function foo(value){
returnIfXXX(value)

return value.YYY * value.ZZZ
}

const fooJumpReturn = value => useJumpReturn(() => foo(value))

function main(){
const value1 = fooJumpReturn({XXX: 1, ZZZ: 3})
console.log(value1)
const value2 = fooJumpReturn({YYY: 2, ZZZ: 4})
console.log(value2)
}
main()

とか