ホームページ  >  記事  >  ウェブフロントエンド  >  JavaScriptアーキテクチャ設計におけるModuleパターンの使用例を詳しく解説

JavaScriptアーキテクチャ設計におけるModuleパターンの使用例を詳しく解説

伊谢尔伦
伊谢尔伦オリジナル
2017-07-24 13:50:462103ブラウズ

モジュール パターンは、中括弧を介してプライベート変数、メソッド、および状態をカプセル化することができ、通常、このデザイン パターンでは 1 つの API のみが返されます。他のすべてのコンテンツはプライベートとしてカプセル化されます。

さらに、このパターンは自己実行関数式と似ていますが、唯一の違いは、モジュールがオブジェクトを返すのに対し、自己実行関数式は関数を返すことです。

ご存知のとおり、JavaScript には他の言語のようなアクセス修飾子がありません。フィールドやメソッドごとにプライベート修飾子とパブリック修飾子を宣言することはできません。つまり、いくつかのパブリック メソッドを含むオブジェクトを返します。これらのメソッドには内部オブジェクトを呼び出す機能があります。

次のコードを見てください。このコードは、グローバル オブジェクト BasketModule を含んでいます。そのため、プログラム全体はこのプライベート配列にアクセスできません。この 3 つのメソッド (addItem、getItemCount、getTotal など) が返され、プライベート バスケット配列にアクセスできます。


var basketModule = (function() {
var basket = []; //private
return { //exposed to public
  addItem: function(values) {
    basket.push(values);
  },
  getItemCount: function() {
    return basket.length;
  },
  getTotal: function(){
    var q = this.getItemCount(),p=0;
    while(q--){
    p+= basket[q].price;
    }
    return p;
  }
 }
}());

また、返すオブジェクトは直接 BasketModule に割り当てられるので、次のように使用できることにも注意してください:


//basketModule is an object with properties which can also be methods
basketModule.addItem({item:'bread',price:0.5});
basketModule.addItem({item:'butter',price:0.3});
 
console.log(basketModule.getItemCount());
console.log(basketModule.getTotal());
 
//however, the following will not work:
console.log(basketModule.basket);// (undefined as not inside the returned object)
console.log(basket); //(only exists within the scope of the closure)

さまざまな一般的なライブラリ (Dojo、jQuery など) でどのように動作するのかする?

Dojo

Dojo は、クラススタイルの宣言メソッドを提供するために dojo.declare を使用しようとします。たとえば、ストア名前空間でバスケット オブジェクトを宣言する場合、これを使用できます。これは次のことができます:


//traditional way
var store = window.store || {};
store.basket = store.basket || {};
 
//using dojo.setObject
dojo.setObject("store.basket.object", (function() {
  var basket = [];
  function privateMethod() {
    console.log(basket);
  }
  return {
    publicMethod: function(){
      privateMethod();
    }
   };
}()));

dojo.provide と一緒に使用すると、非常に強力です。

YUI

次のコードはYUIのオリジナルの実装です:

jQuery

jQueryにはモジュールパターンの実装がたくさんあります。ライブラリ関数を見てみましょう。新しいライブラリを宣言し、ライブラリの作成時に document.ready の init メソッドを自動的に実行します。

YAHOO.store.basket = function () {

 //"private" variables:
 var myPrivateVar = "I can be accessed only within YAHOO.store.basket .";

 //"private" method:
 var myPrivateMethod = function () {
 YAHOO.log("I can be accessed only from within YAHOO.store.basket");
 }

 return {
 myPublicProperty: "I'm a public property.",
 myPublicMethod: function () {
  YAHOO.log("I'm a public method.");

  //Within basket, I can access "private" vars and methods:
  YAHOO.log(myPrivateVar);
  YAHOO.log(myPrivateMethod());

  //The native scope of myPublicMethod is store so we can
  //access public members using "this":
  YAHOO.log(this.myPublicProperty);
 }
 };

} ();

オブジェクトのセルフファセット

オブジェクトのセルフファセットは中括弧を使用して宣言されており、属性フィールドのpublice/privateを使用する場合にnewキーワードを使用する必要はありません。モジュールがそうでない場合は、この方法を使用できますが、この方法は JSON とは異なることに注意してください。オブジェクト self-face: var item={name: "tom"、value:123} JSON: var item={"name":"tom"、"value":123}。

function library(module) {
  $(function() {
    if (module.init) {
      module.init();
    }
  });
  return module;
}
 
var myLibrary = library(function() {
  return {
    init: function() {
      /*implementation*/
      }
  };
}());

CommonJS

CommonJS の導入については、これまでに多くの記事で紹介されていますが、ここで言及したいのは、CommonJS には 2 つの重要なパラメータがあるということです。 standard.exports と require、exports はロードされるモジュールを表し、require はこれらのロードされたモジュールが他のモジュールに依存する必要があり、またロードされる必要があることを表します。

var myModule = {
 myProperty: 'someValue',
 //object literals can contain properties and methods.
 //here, another object is defined for configuration
 //purposes:
 myConfig: {
 useCaching: true,
 language: 'en'
 },
 //a very basic method
 myMethod: function () {
 console.log('I can haz functionality?');
 },
 //output a value based on current configuration
 myMethod2: function () {
 console.log('Caching is:' + (this.myConfig.useCaching) ? 'enabled' : 'disabled');
 },
 //override the current configuration
 myMethod3: function (newConfig) {
 if (typeof newConfig == 'object') {
  this.myConfig = newConfig;
  console.log(this.myConfig.language);
 }
 }
};

 
myModule.myMethod(); //I can haz functionality
myModule.myMethod2(); //outputs enabled
myModule.myMethod3({ language: 'fr', useCaching: false }); //fr

CommonJS の標準モジュール読み込み実装はたくさんありますが、私が気に入っているのは RequireJS です。まず、画像を A​​SCII コードに変換するなど、簡単な例を見てみましょう。エンコーダ モジュールをロードし、その encodeToASCII メソッドを取得します。理論的には、コードは次のようになります:


/*
Example of achieving compatibility with AMD and standard CommonJS by putting boilerplate around the standard CommonJS module format:
*/
 
(function(define){
  define(function(require,exports){
    // module contents
    var dep1 = require("dep1");
    exports.someExportedFunction = function(){...};
    //...
  });
})(typeof define=="function"?define:function(factory){factory(require,exports)});

しかし、encodeToASCII 関数がウィンドウ オブジェクトにアタッチされていないため、上記のコードは機能しません。 、改善されたコードは次のようにする必要があります:


var encodeToASCII = require("encoder").encodeToASCII;
exports.encodeSomeSource = function(){
  //其它操作以后,然后调用encodeToASCII
}

以上がJavaScriptアーキテクチャ設計におけるModuleパターンの使用例を詳しく解説の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。