77

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

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

4

10 に答える 10

89

ここでの最善の策は、単一のグローバルスコープの変数を定義し、そこに変数をダンプすることだと思います:

var MyApp = {}; // Globally scoped object

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

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

上記のようなことをしても、だれもあなたに怒鳴ってはいけません。

于 2009-01-02T15:24:13.383 に答える
62

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

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

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

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

function B(r)
{
    use_rand_num(r);
}
于 2009-01-02T15:22:21.237 に答える
16

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

(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
    };
})();

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

于 2009-01-02T15:33:51.260 に答える
9

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

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));

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

于 2009-01-02T15:23:05.010 に答える
4

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

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

于 2009-01-02T15:21:27.383 に答える
3

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

于 2009-01-02T15:22:24.993 に答える
2

もう 1 つのアプローチは、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

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

于 2013-02-23T15:48:50.877 に答える
1

カスタムjQueryイベントを使用して、JavaScript関数の実行を完全に制御(およびそれらの間で変数を渡す)できます...これらのフォーラム全体でこれは不可能であると言われましたが、それを正確に実行する何かが得られました( ajax呼び出し)。

これが答えです(重要:それはチェックされた答えではなく、私による「エミール」の答えです):

複数の関数間で返される変数を取得する方法-Javascript/jQuery

于 2010-08-22T07:54:29.377 に答える
1

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

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

于 2009-01-02T15:23:26.570 に答える