3

これら2つのJavaScriptモジュールパターンの機能に違いはありますか?

var MODULE = (function() {

    var privvy = "I'm private!";

    return {
        getPublic: function() {
            return "I'm public";
        },      
        getPriv: function() {
            return privvy;
        }       
    };
}());

var MODULE = (function() {

    var privvy = "I'm private!";

    return new function() {
        this.getPublic = function() {
            return "I'm public";
        };
        this.getPriv = function() {
            return privvy;
        };
    };
}());

何が起こっているのかというと、最初に、2つのパブリックメンバーを持つオブジェクトが明示的に宣言されてから返されることだと思います。メンバーの1つには、「private」変数への参照を持つ値としての関数があります(つまり、クロージャはすぐに実行される関数によって形成されますが、getPublic()メソッドは、この関数の実行が終了した後もこの変数にアクセスできます-おもう)

2つ目は、パブリックにアクセス可能な変数に2つの関数を割り当てる匿名コンストラクターを使用してオブジェクトを作成し、IEFが同じ方法でpriv変数へのアクセスを制限するクロージャーを作成します。

これらの2つのバリエーションは、まったく同じオブジェクトになりますか?

4

3 に答える 3

2

それらは機能的に違いはありません。オブジェクトはどちらのMODULE方法でも同じように機能しますが、構文がより簡潔であるため、最初の方法が優先されます。とは必要ありませnewthis

JSLintはこれを裏付けています。return new function() {2番目のパターンでは、「奇妙な構造」であると文句を言います。

編集: @zzzzBov と @Bergi が指摘したように、オブジェクトのプロトタイプに関して違いがあります。詳細な説明については、彼らの回答を参照してください。

于 2012-06-26T14:02:52.477 に答える
2

2 つのバージョンは非常にわずかに異なります。参考までに、基本フォーマットの簡単な例を追加しました ( Version A & Version B )。機能に大きな違いはありませんが、バージョン Bではスコープのレイヤーが追加されています。

var foo; //global scope
var module = (function () {
    var foo; //module scope
    return new function () {
        var foo; //inner scope
    };
}());

さらに、バージョン Aで返されるオブジェクトのプロトタイプは になりますがObject.prototypeバージョン Bでは、プロトタイプは無名関数のプロトタイプになります。

この違いは、モジュールの__proto__プロパティを に対してObject.prototypeチェックすることで確認できます。


バージョン Aは基本的に次の省略形です。

var module = (function () {
    var temp;
    temp = new Object();
    temp.foo = function () {...};
    return temp;
}());

バージョン Bは基本的に次の省略形です。

var module = (function () {
    function anon() {
        this.foo = function () {...};
    }
    return new anon();
}());

バージョン A

var module = (function () {
    return {...};
}());

バージョン B

var module = (function () {
    return new function () {...};
}());
于 2012-06-26T14:10:53.267 に答える
2

結果に大きな違いはありませんが、2 番目の例のオブジェクトには、その無名関数を指す (列挙不可能な) プロトタイプ プロパティ "constructor" があります。つまり、 でコピーを作成できますnew MODULE.constructor

シングルトン オブジェクトを作成するときは、最初の構文が優先されます。2 番目の例は通常、newキーワードなしで使用され、同じ (「静的」)変数MODULEにすべてアクセスしてインスタンスを作成できるようにコンストラクターを返します。priv

同様の結果で別のパターンを投入できます。

var MODULE = new function() {
    var priv = "I'm private!";
    this.getPublic = function() {
        return "I'm public";
    };
    this.getPriv = function() {
        return priv;
    };
}();

最初の例のように動作しますがpriv、静的変数を共有する代わりに新しい変数を作成するコンストラクターをリークします。

于 2012-06-26T14:11:40.970 に答える