web-dev-qa-db-ja.com

グローバル変数を使用せずに他の関数から変数にアクセスする

さまざまな場所から、グローバル変数は本質的に厄介で邪悪であると聞いていますが、オブジェクト指向ではないJavascriptを実行すると、それらを回避する方法がわかりません。乱数やものを使用した複雑なアルゴリズムを使用して数値を生成する関数がありますが、コールバックなどの別の関数でその特定の数値を使用し続ける必要があるため、同じ関数に含めることはできません。

元々生成された番号がローカル変数である場合、そこからアクセスすることはできません。関数がオブジェクトメソッドである場合、数値をプロパティにすることができますが、そうではなく、プログラム構造全体を変更してこれを行うのはやや複雑です。グローバル変数は本当に悪いですか?

64
John Richardson

関数Aで計算された変数を関数Bで表示するには、3つの選択肢があります。

  • グローバル化して、
  • オブジェクトのプロパティにする、または
  • aからBを呼び出すときにパラメーターとして渡します。

プログラムがかなり小さい場合、グローバルはそれほど悪くありません。それ以外の場合は、3番目の方法の使用を検討します。

function A()
{
    var Rand_num = calculate_random_number();
    B(Rand_num);
}

function B(r)
{
    use_Rand_num(r);
}
52
Paul Stephenson

ここでの最善の策は、single global-scoped変数を定義し、そこに変数をダンプすることです。

var MyApp = {}; // Globally scoped object

function foo(){
    MyApp.color = 'green';
}

function bar(){
    alert(MyApp.color); // Alerts 'green'
} 

上記のようなことをすることに対して誰もあなたに怒鳴るべきではありません。

72
Triptych

名前空間の使用を検討してください。

(function() {
    var local_var = 'foo';
    global_var = 'bar'; // this.global_var and window.global_var also work

    function local_function() {}
    global_function = function() {};
})();

local_functionglobal_functionの両方が、すべてのローカル変数とグローバル変数にアクセスできます。

編集:別の一般的なパターン:

var ns = (function() {
    // local stuff
    function foo() {}
    function bar() {}
    function baz() {} // this one stays invisible

    // stuff visible in namespace object
    return {
        foo : foo,
        bar : bar
    };
})();

returnedプロパティは、名前空間オブジェクトを介してアクセスできるようになりました。 ns.foo、ただしローカル定義へのアクセスを保持します。

15
Christoph

あなたが探しているものは、技術的にはカレーとして知られています。

function getMyCallback(randomValue)
{
    return function(otherParam)
    {
        return randomValue * otherParam //or whatever it is you are doing.
    }

}

var myCallback = getMyCallBack(getRand())

alert(myCallBack(1));
alert(myCallBack(2));

上記は正確にカリー化された関数ではありませんが、グローバル名前空間に変数を追加したり、他のオブジェクトリポジトリを必要とせずに既存の値を維持した結果を達成します。

7
AnthonyWJones

別の関数が変数を使用する必要がある場合、引数として関数に渡します。

また、グローバル変数は本質的に厄介でも悪でもありません。それらが適切に使用されている限り、それらに問題はありません。

4
Adam Peck

別のアプローチは、Douglas Crockfordフォーラムの投稿から取り上げたものです( http://bytes.com/topic/javascript/answers/512361-array-objects )。ここにあります...

ダグラス・クロックフォードは書きました:

2006年7月15日

「IDでオブジェクトを取得する場合は、配列ではなくオブジェクトを使用する必要があります。関数はオブジェクトでもあるため、関数自体にメンバーを格納できます。」

function objFacility(id, name, adr, city, state, Zip) {

    return objFacility[id] = {

        id: id,
        name: name,
        adr: adr,
        city: city,
        state: state,
        Zip: Zip

    }
}

objFacility('wlevine', 'Levine', '23 Skid Row', 'Springfield', 'Il', 10010);

「オブジェクトは次の方法で取得できます」

objFacility.wlevine

オブジェクトのプロパティは、他の関数内からアクセスできるようになりました。

3
Joel Erenberg

私はこれが元の質問に関連して非常に役立つことがわかりました:

FunctionOneで使用する値を返し、functionTwo内でfunctionOneを呼び出し、結果を新しい変数に配置し、この新しい変数をfunctionTwo内で参照します。これにより、functionTwo内でfunctionOneで宣言されたvarを使用できるようになります。

function functionOne() {
  var variableThree = 3;
  return variableThree;
}

function functionTwo() {
  var variableOne = 1;
  var var3 = functionOne();

  var result = var3 - variableOne;

  console.log(variableOne);
  console.log(var3);
  console.log('functional result: ' + result);
}

functionTwo();
3
gav_aus_web

このコードを再利用する可能性がある場合は、おそらくオブジェクト指向の観点に沿って努力するでしょう。グローバル名前空間の使用は危険な場合があります。再利用される変数名が原因でバグを見つけるのが困難になるリスクがあります。通常は、単純なコールバック以外の目的でオブジェクト指向のアプローチを使用することから始めます。これにより、書き直す必要がなくなります。 javascriptに関連する関数のグループがあるときはいつでも、オブジェクト指向アプローチの候補になると思います。

2
tvanfosson

私はあなたの問題の詳細を知りませんが、関数が値を必要とする場合、それは呼び出しを介して渡されるパラメータである可能性があります。

グローバルは悪い状態であると見なされます。グローバル状態と複数の修飾子により、追跡が困難なコードや奇妙なエラーが発生する可能性があるためです。何かをいじる多くの俳優にとっては、混乱を引き起こす可能性があります。

1
Arthur Thomas

カスタムjQueryイベントを使用して、javascript関数の実行を完全に制御(およびそれらの間で変数を渡す)することができます。 ajax呼び出し)。

答えは次のとおりです(重要:チェックされた答えではなく、「Emile」という私による答えです):

複数の関数で変数を返す方法-Javascript/jQuery

1
Kyle