なので極力スコープは小さくしたいのですが 関数内だけ使う関数ってどこにあるのが良いのでしょうか?
const fn1 = () => {
const fn2 = () => {
}
fn2()
}
const fn3 = () => {
}
こんな感じのもので fn2 は fn1 の中でしか使いません
fn1 でしか使わないので fn1 の中 つまり今の場所でいいように思います
しかし fn1 のコードが長くなり fn1 の中に fn2 相当の関数が 5 や 10 になってくると fn1 関数がとても長くなり見づらくなります
関数内関数を無視して fn1 だけを見ると数十行程度なのに fn1 全体としては 数百行とかいうケースもありえます
また fn1 内のローカル変数がいくつもあると fn2 などの関数はそれらすべてを見ることができます
fn2 は外側を一切見ない関数だとしてもスコープ的には見れるので 読むときにはそれらを参照するかもしれないとして読む必要があります
そういうことを考えると
const fn1 = () => {
fn2()
}
const fn2 = () => {
}
const fn3 = () => {
}
でもいいのではと思うのですよね
fn2 は fn1 内のローカル変数を見ることができません
見れるのはグローバルやモジュール内の変数のみです
fn1 のローカル変数とは切り離されているので 読みやすくなります
また fn1 の中は fn1 で直接行う処理のみなので fn1 の行数も減ってスッキリします
しかし fn2 がモジュールのトップレベルに出てくることで fn3 が fn2 を参照できるようになってしまいます
今度は fn3 が fn2 を使うかもという部分を考えないといけません
いずれも全体として短いこれくらいだとどっちでもいいレベルですが 長くなってくると読みづらくなるんですよね
ただ fn3 が fn2 を見れても関数呼び出しだけです
それに対して fn2 が fn1 のローカル変数を見れるのは値の書き換えができるので複雑度が上がります
なのでどっちかというと関数内関数を減らしたほうがいいのかなと思ったりはするものの 本当にベストなのか疑問が残ります
別の手段としてモジュールを分けてしまうのがいいのかとも思ったりはしてますが モジュール数が結構増えそうで 結局試してません
分けるとしたらこういう感じです
// sub.js
export const fn1 = () => {
fn2()
}
const fn2 = () => {
}
// main.js
import { fn1 } from "./module1.js"
const fn3 = () => {
}
fn1 が読みづらいくらい長くなるなら fn1 だけを別モジュールに切り出して fn1 と fn2 をトップレベルに置きます
エクスポートは fn1 だけにして fn3 からは fn2 を参照できなくします
ただこれも トップレベルじゃないとできないです
親スコープを参照したいから関数内関数にしてるところがあって その中で今回みたいなことをしたい場合にはモジュールに分けるということはできないです