私はその本を読んでいますJavaScript デザインパターンの学習最近、モジュール パターンと公開モジュール パターンの違いがわかりません。同じものだと思います。誰か例を挙げてもらえますか?
ベストアンサー1
モジュール パターンを実装する方法は少なくとも 3 つありますが、Revealing Module Pattern は正式な名前を持つ唯一のモジュール パターンの派生です。
基本的なモジュールパターン
モジュール パターンは、次の条件を満たす必要があります。
- プライベートメンバーは閉鎖中に住んでいます。
- パブリック メンバーは戻りオブジェクトで公開されます。
しかし、この定義には多くの曖昧さがあります。この曖昧さを別の方法で解決すると、モジュール パターンのバリエーションが得られます。
モジュールパターンの公開
公開モジュールパターンは、モジュールパターンのバリエーションの中で最も有名で人気があります。他の選択肢に比べて、次のような多くの利点があります。
- 関数本体を変更せずにパブリック関数の名前を変更します。
- 関数本体を変更せずに、1 行を変更するだけで、メンバーをパブリックからプライベートに、またはその逆に変更できます。
RMP は、元の条件に加えて、次の 3 つの追加条件を満たしています。
- パブリックかプライベートかに関係なく、すべてのメンバーはクロージャ内で定義されます。
- 戻りオブジェクトは関数定義のないオブジェクトリテラルです。右辺の式はすべてクロージャ変数です。
- すべての参照は、戻りオブジェクトではなく、クロージャ変数を介して行われます。
次の例は、それがどのように使用されるかを示しています。
var welcomeModule = (function(){
var name = "John";
var hello = function(){ console.log("Hello, " + name + "!");}
var welcome = function() { console.log( hello() + " Welcome to StackOverflow!");}
return {
name: name,
sayHello: hello,
sayWelcome: welcome
}
})();
name
非公開にしたい場合はsayHello
、戻りオブジェクト内の適切な行をコメントアウトするだけです。
var welcomeModule = (function(){
var name = "John";
var hello = function(){ console.log("Hello, " + name + "!");}
var welcome = function() { console.log( hello() + " Welcome to StackOverflow!");}
return {
//name: name,
//sayHello: hello,
sayWelcome: welcome
}
})();
オブジェクトリテラルを使用したモジュールパターン
これはおそらくモジュール パターンの最も古いバリエーションです。RMP とは異なり、このバリエーションには魅力的な公式名はありません。
元の条件に加えて、次の条件を満たしています。
- プライベート メンバーはクロージャ内で定義されます。
- パブリック メンバーは、戻りオブジェクト リテラルで定義されます。
- パブリック メンバーへの参照は
this
、可能な限り を介して行われます。
次の例では、RMP とは対照的に、関数定義が実際には戻りオブジェクト リテラル内にあり、メンバーへの参照が によって修飾されていることがわかりますthis
。
var welcomeModule = (function(){
return {
name: "John",
sayHello: function(){ console.log("Hello, " + this.name + "!");}
sayWelcome: function() { console.log( this.hello() + " Welcome to StackOverflow!");}
}
})();
name
RMP とは異なり、と をプライベートにするには、さまざまな関数本体の定義内のと をsayHello
指す参照も変更する必要があることに注意してください。name
sayHello
var welcomeModule = (function(){
var name = "John";
var sayHello = function(){ console.log("Hello, " + name + "!");};
return {
//name: "John",
//sayHello: function(){ console.log("Hello, " + this.name + "!");}
sayWelcome: function() { console.log( hello() + " Welcome to StackOverflow!");}
}
})();
リターンオブジェクトスタブを使用したモジュールパターン
この変種にも正式な名前はありません。
元の条件に加えて、次の条件を満たしています。
- 最初に空の戻りオブジェクト スタブが定義されます。
- プライベート メンバーはクロージャ内で定義されます。
- パブリックメンバーはスタブのメンバーとして定義されます
- パブリックメンバーへの参照はスタブオブジェクトを介して行われます
以前の例を使用すると、パブリック メンバーがスタブ オブジェクトに直接追加されることがわかります。
var welcomeModule = (function(){
var stub = {};
stub.name = "John";
stub.sayHello = function(){ console.log("Hello, " + stub.name + "!");}
stub.sayWelcome = function() { console.log( stub.hello() + " Welcome to StackOverflow!");}
return stub;
})();
name
以前と同じように非公開にしたい場合はsayHello
、現在非公開になっているメンバーへの参照を変更する必要があります。
var welcomeModule = (function(){
var stub = {};
var name = "John";
var sayHello = function(){ console.log("Hello, " + name + "!");}
stub.sayWelcome = function() { console.log( hello() + " Welcome to StackOverflow!");}
return stub;
})();
まとめ
公開モジュールパターンと他のモジュールパターンの違いは、主にパブリックメンバーの参照方法にあります。その結果、RMP は使用と変更がはるかに簡単で、それが人気を博しています。ただし、これらの利点には大きな代償が伴います (私の意見では)。Addy Osmani は、モジュールパターンの公開、
このパターンの欠点は、プライベート関数がパブリック関数を参照している場合、パッチが必要な場合にそのパブリック関数をオーバーライドできないことです。これは、プライベート関数が引き続きプライベート実装を参照し、パターンがパブリック メンバーには適用されず、関数にのみ適用されるためです。
プライベート変数を参照するパブリック オブジェクト メンバーも、上記のパッチなしルールの注意事項の対象となります。
この結果、Revealing Module パターンで作成されたモジュールは、元の Module パターンで作成されたモジュールよりも壊れやすい可能性があるため、使用時には注意が必要です。