それを可能にする言語で関数をネストする必要がありますか、それを避けるべきですか?


12

JavaScript、PL / SQL、および他のいくつかの言語では、関数をネストできます。つまり、別の関数内で宣言できます。これは、大きな機能を小さな部分に分割するために使用できますが、それらの部分を大きな機能のコンテキスト内に保持します。

function doTooMuch() {
    function doSomething () {
       ...
    }
    function doSomethingElse() {
       ...
    }
    function doYetAnotherThing() {
       ...
    }

    // doTooMuch body

    doSomething();
    doSomethingElse();
    doYetAnotherThing();
}

場合によっては、これらの小さい関数が大きい関数のローカル変数を使用しない場合、これはすべての関数がネストされていないバージョンに簡単に変更できます。

function doSomething () {
   ...
}
function doSomethingElse() {
   ...
}
function doYetAnotherThing() {
   ...
}
function doTooMuch() {
    doSomething();
    doSomethingElse();
    doYetAnotherThing();
}

これらのネストされた関数を他の場所で使用しないと仮定すると、それらを大きな関数のコンテキスト内に保持する方が良いでしょうか、それが悪いのですか?

回答:


8

それは意見の問題ですが、実際にあなたの設計の必要かつ意図的な部分でない限り、関数のネストは避けたいと思います。

ほとんどの言語で関数をネストすると、何らかの機械的効果が生じます。最も一般的で興味深いのは、本体内で使用できる変数の字句スコープを閉じることですが、他のもの(例:関数の可視性)も時々表示されます。

これらは通常、適切に使用すると素晴らしいツールですが、複雑なツールです。コードを最初に見ると、非ローカルまたは非自明な効果が生じる可能性があるためです。

あなたがそれらを使用しない場合、多くの人々はコードを読んで、それをしているものを見ないでしょう-だから、彼らはそれを見逃したと仮定し、もう一度見て、あなたがそのようにした理由を解決しようとします。

また、将来のプログラマが意図しないものを意図的に、または偶然に閉じてしまうリスクもあります。

最後に、関数宣言が、囲んでいる関数のスコープ外で名前付き関数を宣言している場合は、避けてください。それは誰にとっても非常に紛らわしいです。

最後のメモに関して:個々の関数はコードの区切りに役立つため、関数をネストすることは単一の巨大な関数よりも面倒ではありませんが、最終的に理解するためにより多くのコードを読むことを意味しますdoTooMuch()-特にネストされた関数宣言の間でコードを隠すことができる場合、または誰もしなかったことを確認する必要があります。


-1:Javascriptは「ほとんどの言語」ではありません。Javascriptでの関数のネストは通常​​の方法です。
ケビンクライン

2
JavaScriptでネスティング機能を@kevinclineすることは一般的に悪い習慣です
レイノス

@Raynos:ネストしない場合、どこに配置しますか?あなたはそれらを含むクラスはありません。ここではいくつかの典型的なコードは次のとおりです。jquery(function($){ $('#id').click(function(){...}); }
ケビン・クライン

@kevincline ...初心者向けの典型的なコード、1つの深いネストされた関数が必要です。また、javascriptにはモジュールスコープがないため、匿名のクロージャーが必要です。
Raynos

そして、そのクリックが完了コールバックでAjax呼び出しを実行する場合はどうなりますか?これで、2つのレベルにネストされた関数ができました。もちろん、変数に匿名のクロージャーを割り当てることで、ネストを制限できます。それは本当に良いですか?
ケビンクライン

2

これは正解のない質問の1つで、「個人的な好み」、「チーム練習」などの言葉が思い浮かびます。私の意見では、特に名前を付けられない場合、親関数の内部ではどこにも使用されない小さな関数(ここでは別の主観的なもの)が属します。


0

どちらの選択肢もカプセル化を最大化しないため、この質問には正しい答えがありません。あなたがそれらをネストする場合、彼らはまだすべきではない変数にアクセスできます。そうしないと、他の関数はアクセスすべきでない関数にアクセスできます。どちらにしても、負けです。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.