web-dev-qa-db-ja.com

メソッドのパラメーター化とグローバル変数

私のコードが成長し始めるとき、私をしばらく悩ませてきた非常に単純な質問があります。

ネストされた関数呼び出しの長いルートを通過するときに、パラメーターをグローバル変数で置き換える必要がありますか?

多くの関数が共有変数を変更できるため、グローバル環境ではプログラムの状態が予測不可能になる可能性があることを理解していますが、それでもグローバル空間を使用すると非常に簡単になります。

私自身について説明しましょう:

functionA(){
   x = something
   functionB(x)
}
functionB(x){
   functionC(x)
}
functionC(x){
   finallyDoSomethingWithX(x)
}
finallyDoSomethingWithX(x){
  x += 1 //Very dummy example ignoring pass by value, not reference.
}

と取り換える:

globalX;
functionA(){
   globalX = something
   functionB()
}
...
...
...
finallyDoSomethingWithX(){
   globalX += 1
}

2番目の方法は、パラメーターが簡単に蓄積され、コードを再利用する必要がある場合に非常に制限される可能性があるため、プログラムに非常に自由を与えると感じますが、同時に、変数に関連する関数はモジュール性を失うように感じますグローバル環境では、たとえば、別の変数finallyDoSomethingWithXglobalXを操作したい場合にも、再利用性が失われます。

私は実際にデザインパターンを使用していないため、これは私に起こっていると思います。私はJavascriptでプログラミングしているためです。これは、私にとって、中規模プロジェクトでは1つのスクリプトですべてを扱う言語のように感じます。

何かアドバイスは?パターン?必要に応じて、より具体的にすることができます。

10
AFP_555

グローバル変数を使用しないでください。

また、関数のチェーンにパラメーターを渡さないでください!

実際の例を使わないので難しいです。しかし、通常はより良いアプローチがあります。

さまざまな低レベル関数で使用されるAPIを呼び出すために使用する必要があるパスワード変数があるとします。

グローバルなアプローチ(psudoコード)

var pass;

function multiply(a,b) {
   return apiMultiply(pass,a,b);
}

パラメータを渡す方法

function multiply(a,b,pass) {
    return apiMultiply(pass,a,b);
}

オブジェクトアプローチ

class math {
    var api;
    constructor(pass) {
        api = new api(pass);
    }

    function Multiply(a,b) {
        api.Multiply(a,b); //uses pass from constructor
    }
}
7
Ewan

ペストのようなグローバルは避けてください。

どのコードでもグローバルを変更できます。チェーンがある場合A(x)-> B(x)-> C(x)- > ...-> Z(x)、xをグローバルXに格納すると、チェーンA-> B-> C-> ...-> Zがあり、その長いチェーンのすべてのステップで、または完全に独立したコードでは、誰かがXを変更する可能性があります。Zが使用する値は、Aが開始した値とは完全に異なる可能性があります。

あなたのコードがそれがすることになっていることを確実にしたい、またはあなたがそれがあなたが思っていることをしていることを確実にしたいなら、それは悪夢です。

3
gnasher729