0

なぜこれが期待どおりに機能しないのですか。(予想されるコメントを参照)

var Module = function () {
    var public_instance_var;

    function doStuff () {
        Module.doOtherStuff();
        console.log(public_instance_var); // expected: true, but logs undefined
    };

    function doOtherStuff() {
        public_instance_var = true;
    };

    return {
        public_instance_var: instance_var,
        doStuff: doStuff,
        doOtherStuff: doOtherStuff
    }
}();

Module.doStuff();

更新: jAndy のいくつかの提案に応じて修正

4

3 に答える 3

0

このコードが行うことは、簡単に言えば、関数を作成して実行し、その戻り値を変数に代入することです: Module. 戻り値は、1 つのプロパティを持つオブジェクトです: 、変数または (タイプミスを修正した後: )public_instance_varを指します。この変数は宣言されましたが、インスタンス化されていません。したがって、戻り値は次のようになります。instance_varpublic_instance_var

Module.public_instance_var = undefined

最後の行Module.doStuff();は少し機能しません。モジュールはメソッドを持たないオブジェクトです。宣言した関数は、無名関数が戻るときにガベージ コレクションされます。これらの関数にアクセスしたい場合は、それらを return ステートメントに含める必要があります。クロージャー、オブジェクト コンストラクター、およびデザイン パターン全般について読んでください。

var Module = (function()
    var public_instance_var;
    function doStuff () {
        this.doOtherStuff();
        console.log(public_instance_var); // expected: true, but logs undefined
    };
    function doOtherStuff() {
        public_instance_var = true;
    };
    return {
        public_instance_var: public_instance_var,
        doStuff: doStuff,
        doOtherStuff: doOtherStuff
    };
})();

もちろん、このように変数public_instance_varはパブリック プロパティであるため、実際にやろうとしていることは、プライベート プロパティとメソッドをシミュレートすることだと思います。その場合、次のようなコードになる可能性があります。

var Module = (function()
{
    var public_instance_var;
    return {
        //public_instance_var: public_instance_var, remove this line
        //the closure will preserve access to the variable
        doStuff: function ()
        {
            this.doOtherStuff();//this, you're referencing the object's property
            console.log('here I am');
        },
        doOtherStuff: function ()
        {
            public_instance_var = true;
            //this won't work anymore:
            //this.public_instance_var = true;
        };
    }
})();

Module.doStuff()現在は logs ですhere I amが、doOtherStuff現在は public メソッドでもあります。問題を解決するために選択できる方法は次のとおりです。

var Module = (function()
{
    var public_instance_var;
    function doOtherStuff ()
    {
        public_instance_var = true;
    };
    return {
        //public_instance_var: public_instance_var, remove this line
        //the closure will preserve access to the variable
        doStuff: function ()
        {
            doOtherStuff();//don't use this here, but the reference to the function exists thanks to closure
            console.log('here I am');
            console.log(public_instance_var);//logs true
        }
    };
})();

これらは、オブジェクトを返すクロージャーと関数で実​​行できる非常に強力なことのほんの一部です。この
記事のように、いくつかの記事を読んでください。もっと良い記事があります。Google 用語power constructors

于 2012-07-31T12:17:55.683 に答える
0

ここに複数のエラーがあります:

  • DoStuffモジュールインターフェースとして返さない
  • instance_var宣言されていません。おそらく意味がありますpublic_instance_var
  • doOtherStuffに割り当てられることはありませんModuledoOtherStuff();

固定コード:

var Module = function () {
    var public_instance_var;

    function doStuff() {
        doOtherStuff();
        console.log(public_instance_var); // expected: true, but logs undefined
    };

    function doOtherStuff() {
        public_instance_var = true;
    };

    return {
        doStuff: doStuff,
        public_instance_var: public_instance_var
    }
}();

Module.doStuff();
于 2012-07-31T11:42:28.700 に答える
0

コードを次のように変更します

var Module = function () {
    var public_instance_var;

    function doStuff () {
        doOtherStuff();
        console.log("var is ", public_instance_var); // expected: true, but logs undefined
    };

    function doOtherStuff() {
        public_instance_var = true;
    };

    return {
        public_instance_var: public_instance_var,
        doStuff : doStuff
    }
}();

Module.doStuff();
  • 関数を返す必要がありdoStuff()ます(そうしないと、関数の外では未定義になります)、public_instance_var代わりにinstance_var
  • doOtherStuff()プレフィックスなしで実行する必要がありますModule.
于 2012-07-31T11:46:06.343 に答える