web-dev-qa-db-ja.com

javascript関数で変数を存続させる

関数に変数を格納したいこの変数は、ユーザーの操作に応じて状態が変化します

function plan_state(current){
    if (current != ''){
     state = current;
    }
    else {
     return state;
    }
}

ドキュメントが読み込まれると、plan_state( 'me');を呼び出します。

特定のことが起こったとき、私はplan_state( 'loved')を呼び出すかもしれません

問題は、関数を実行して現在の状態を確認したいことです。

alert(plan_state());

私は未定義に戻り、少なくとも、このオンロードを設定するときに「私」である必要があります。

私は何が間違っているのですか?

16
Daniel Hunter

状態変数は関数内で宣言されているため、関数はステートフルではありません。したがって、関数呼び出しの存続期間中のみ存在します。簡単な解決策は、関数の外部で変数をグローバルに宣言することです。これは 悪い悪い悪い悪い です。

より良いアプローチは、 モジュールパターン を使用することです。これは、JavaScriptの開発に真剣に取り組んでいるかどうかを学ぶために不可欠なパターンです。内部(プライベート変数)を使用して状態を有効にし、状態を変更または取得するための多数のメソッドまたは関数を公開します(オブジェクト指向プログラミングなど)。

_    var stateModule = (function () {
        var state; // Private Variable

        var pub = {};// public object - returned at end of module

        pub.changeState = function (newstate) {
            state = newstate;
        };

        pub.getState = function() {
            return state;
        }

        return pub; // expose externally
    }());
_

したがって、stateModule.changeState("newstate");は状態を設定します

そしてvar theState = stateModule.getState();は状態を取得します

49
reach4thelasers

変数の範囲が「低すぎる」と思います。関数内で変数をパラメーターとして、または明示的にvarとして定義することにより、関数内でのみアクセスできます。目的を達成するために、関数のスコープ外で、よりグローバルなレベルで変数を実装することができます(実際には推奨されません)。

しかし、あなたの質問を読み直した後、それは少し誤解を招きます。 stateに関係なく、currentを返したくないですか?私はあなたがそのような何かを求めているかもしれないと思います:

var state;
function plan_state(current)
{
    if (current != '' && current != state)
    {
        state = current;
    }
    return state;
} 

代替オブジェクト構造:

function StateManager(state)
{
    this.state = state;

    this.getState = function(current)
    {
        if (current != '' && current != this.state)
        {
            this.state = current;
        }
        return this.state;
    }
}

// usage
var myStateManager = new StateManager("initial state here");
var theState = myStateManager.getState("some other state");
1
Richard