1

重複の可能性:
Javascript: モジュール パターン vs コンストラクター/プロトタイプ パターン?

javaScript でクラス エミュレーションを使用したい。これは好みです。

モジュールパターンを使用してきましたが、パブリックおよびプライベートのメンバー変数と関数を作成できるため、単純な関数オブジェクトのみを使用することを検討しています。

クラスをエミュレートする関数オブジェクトの例を次に示します

var input = document.getElementById('input');
var output = document.getElementById('output');

function test()
{
    var private_var = 'private_var';
    var private_func = function(){ return 'private_func';};
    var my = {};
    my.public_var = 'public_var';
    my.public_func = function(){ return 'public_func';};
    return my;
}

var object_test = new test();

alert( '| ' + object_test.public_var);
alert( '| ' + object_test.private_var);

alert( '| ' + object_test.public_func() );
alert( '| ' + object_test.private_func() );

​

クラスをエミュレートするモジュール パターンの例を次に示します

主な違いは何ですか? 暗黙のグローバルを明示的にする機能以外に、何かありますか?

4

2 に答える 2

2

「関数オブジェクト」の意味を誤解しているかもしれませんが、私が理解しているように、これらのパターンは実際には互換性がありません。

「モジュールパターン」は、必要に応じてメソッドとプロパティを使用して単一のオブジェクトを定義するためのものです。この良い例は次のとおりです。Mathカスタムモジュールの簡単な例は単なるObjectインスタンスです。

var Module = { prop: 'prop' };
alert(Module.prop);

しかし、このように、モジュールはクラスではありません。それらを使用するために電話する必要はありませんnew Math。メソッドを呼び出す(Math.abs())か、プロパティを取得/設定する(Math.PI)。

関数オブジェクト」(またはコンストラクターを意味するもの)は、JavaScriptが持つ「クラス」定義に最も近い概念です。Object、、。String_ Arrayこれらおよびその他は、新しいインスタンスを作成するために定義されたコンストラクターです。

あなたが与えたスニペットは確かにコンストラクターに修正することができます:

// common-practice: constructors are named in PascalCase
function Test()
{
    var private_var = 'private_var';
    var private_func = function(){ return 'private_func';};

    this.public_var = 'public_var';
    this.public_func = function(){ return 'public_func';};
}

var object_test = new Test();

また、これらのパターンは必ずしも相互に排他的であるとは限りません。コンストラクターをモジュールのように扱うと、「静的」のようなメンバーを定義できます。

var Foo = (function () {
    function constructor() {
        var private_var = 'private_var';
        this.public_prop = 'public_prop';
    }

    var private_shared = 'private_shared';
    constructor.public_shared = 'public_shared';

    return constructor;
})();

alert(Foo.public_shared);     // 'public_shared' (module property)
alert(new Foo().public_prop); // 'public_prop'   (instance property)
于 2012-05-14T00:33:37.500 に答える
0

主な問題は、あなたの test() 関数が new キーワードなしでも呼び出せることであり、その場合の 'this' の値は、test( ではなく、呼び出し先のコンテキスト (ほとんどの場合グローバル) を指します。 ) 内部クロージャが原因で、グローバル名前空間が汚染されたり、異なるインスタンスが互いの値を上書きしたりするなどの望ましくない影響が生じます。コンストラクター関数を通常の関数として呼び出した場合、インタープリターは警告しません。コードが多くの聴衆と共有されることを意図しておらず、コンストラクターの Test() や通常の関数の test() など、コンストラクター関数の命名規則を使用している場合でも、安全です。また、すべてが隣接する return ステートメントで「パブリック」メンバーを定義することを強制するなど、コードの規律を維持するのにも役立ちます。きれいなファサードとして機能します。これは、大規模なコード ベースでは興味深いものです。

于 2012-05-13T22:15:00.080 に答える