JavaScriptモード(11):モジュールモード

7387 ワード

誘引子
この文章は第9編の中の内容の発散と補充に対してと言えて、その時私はただモジュールモードの中のいくつか内容を簡単に関数編の中に帰するだけで、北川の注意のもとで、私はやっとこれが非常に厳格ではないことに気づきました.
モジュールモードとは?
JavaScriptにはパッケージの概念がなく、ますます巨大なJavaScriptコードに直面しています.これはモジュール開発の切実な需要を促しています.だから、JavaScriptのモジュールモデルが誕生しました.最初にこのように呼ばれたのは古い道です.彼はモジュールモードと呼ばれています.
モジュールモードは、独立して結合されたコードセグメントを作成するためのツールを提供しています.これらのコードはブラックボックスとして使用できます.書き込み中のソフトウェア要求が変化したとき、これらのコードは追加、置換、除去されます.
モジュールモードはいくつかのパターンの組み合わせです.彼は含まれています.
  • 名前空間モード
  • 依存宣言モード
  • プライベートと特権メンバーモード
  • リアルタイム関数モード
  • 次に彼の構成パターンを例に合わせて展開します.
    名前空間モード
    モジュール化の目的は、大規模なプログラム開発をサポートし、コードブロックの組み立てを処理し、コードを正確に実行させることです.私たちが望まないモジュールコードを含めても、コードを正しく実行することができます.これを達成するためには、異なるモジュールは、大域的な実行コンテキストの変更を回避しなければならないので、後続のモジュールは、彼らが期待する役割領域内で実行しなければならない.これは実際には、モジュールが全体的な識別情報を定義しないといけないことを意味しています.理想的な状況は、すべてのモジュールが一つのグローバル識別内に定義されています.名前空間はとても良い解決策です.
    JavaScriptには名前空間の概念がないが、この特徴は非常によく実現されている.グローバルオブジェクトを作成し、そのグローバルオブジェクトにすべての機能モジュールを追加して、大量の関数、オブジェクト、その他の変数を持つ場合は、グローバル範囲を汚染しません.
    機能モジュールの増加に伴い、以下のようになります.
    ```javascript
    
    	//      
    
    	var module = module || {};
    
    	// module        
    
    	if (!typeof module === "undefined") {
    
    		module.module1 = {};
    
    	} else {
    
    		var module = {};
    
    		module.module1 = {};
    
    	}
    
    	// module1        
    
    	if (!typeof module === "undefined") {
    
    		if (!typeof module.module1 === "undefined") {
    
    			module.module1.module2 = {};
    
    		} else {
    
    			module.module1 = {};
    
    			module.module1.module2 = {};
    
    		}
    
    	} else {
    
    		var module = {};
    
    		module.module1 = {};
    
    		module.module1.module2 = {};
    
    	}
    
    ```
    
    
    私たちは新しいモジュールを追加するたびに、これらのモジュールが既に存在しているかどうかを確認します.したがって、私たちは名前空間の詳細を処理するために便利な機能が必要です.コードは以下の通りです.
    ```javascript
    
    	//        
    
    	var GLOBAL = GLOBAL || {};
    
    	//         
    
    	GLOBAL.namespace = function(str) {
    
    		var arr = str.split("."),
    
    			o = GLOBAL,i;
                 for (i = (arr[0] == "GLOBAL") ? 1 : 0; i < arr.length; i++) { o[arr[i]] = o[arr[i]] || {}; o = o[arr[i]]; } } // ( ) GLOBAL.namespace("Module1"); // Module1 print GLOBAL.Module1.print = function(msg){ console.log(msg); } // Module1 print GLOBAL.Module1.print("1"); //1 // GLOBAL.Module1.print.call(null, "3"); //3 ```
    この実装は非破壊的です.つまり、この属性が既に存在しているなら、再作成はしません.私たちはモジュールを作る前に登録するだけで、彼が存在するかどうかを管理する必要がありません.そうすると、コード量が大幅に減少します.
    依存を宣言
    これはJavaの依存注入と似ています.機能類は単独で存在することができません.彼はいくつかの「基礎施設」が必要です.例えば私達は胡桃を食べたいです.プログラムの中で、私達が作ったのは通常他のサポートモジュールを導入することです.つまり依存して、それらの簡単な基礎論理を繰り返し書くことを避けました.
    他の言語では、専門的な文法構造があります.JavaScriptでは、簡単に自分で規範化することもできます.コードは以下の通りです
    ```javascript
    
    	GLOBAL.namespace("Nut");
    
    	// “  ”         
    
    	GLOBAL.Nut.eat = function(aNut){
    
    		//  
    
    		var tools = GLOBAL.Tools.spanner;
    
    		//      
    
    		tools.use.call(aNut);
    
    	}
    
    ```
    
    
    これは実際の意味がないコードです.ただ依存を説明するために使うのです.その中の引き金は依存関係です.彼を使ってクルミを食べに来ます.プログラムの中で、私達はこの「板」を導入します.
    簡単ですが、このようにすると多くのメリットがあります.
  • 関数の上部にある声明は、簡単に発見され、解析的な依存性があります.
  • 解析ローカル変数の速度は、全体変数の解析よりも速い
  • .
  • いくつかの圧縮ツールは、それを簡略化し、バイト数を減らすことができる(ツールは局所変数を簡略化し、大域変数は不可能)
  • .
    プライベートと特権のメンバー
    他のoo言語には、prvate、public、interfaceのような文法があり、公共属性、私有属性、公共インターフェースを区別します.しかし、JavaScriptは持っていません.JavaScriptでは対象メンバー全員が公開されています.JavaScriptでは、
    ```javascript	
    
            //      
    
    	var WeiRan = {
    
    		name: "WeiRan",
    
    		getName: function() {
    
    			console.log(this.name);
    
    		}
    
    	}
    
    	//      
    
    	console.log(WeiRan.name); //WeiRan 
    
    	WeiRan.getName(); //WeiRan
    
    	//           
    
    	function Person(name) {
    
    		this.name = name;
    
    		this.getName = function() {
    
    			console.log(this.name);
    
    		}
    
    	}
    
    	//       
    
    	var wr = new Person("WeiRan");
    
    	//      
    
    	console.log(wr.name); //WeiRan
    
    	wr.getName(); //WeiRan
    
    ```
    
    
    私達は字面量の方式を通じて(通って)それとも構造関数の方式を通じて(通って)オブジェクトを創建するのなのに関わらずを発見して、新しいオブジェクトのすべての属性と方法は対外的にすべて公開したので、しかし多くのシーンの下で、私達はすべてのロジックを调节者に暴露したくなくて、これはつまり私達の私有の属性あるいは方法が必要です.JavaScriptにはプライベートメンバーに対する特俗的な文法がないが、クローズドを使ってこの機能を実現することができます.コードは以下の通りです
    ```javascript
    
    	function Person(UserName) {
    
    		//    
    
    		var name = UserName;
    
    		//API
    
    		this.getName = function() {
    
    			console.log(name);
    
    		}
    
    	}
    
    	//       
    
    	var wr = new Person("WeiRan");
    
    	//    
    
    	console.log(wr.name); //undefined
    
    	wr.getName(); //WeiRan
    
    ```
    
    
    私たちは、ローカル変数が特定の作用領域でしかアクセスできないことを知っています.例えば、Personメソッド内部で定義されたローカル変数nameはPerson内でしかアクセスできません.これは私たちのプライベートメンバーの要求にぴったり合っています.getNameのような対外公開の方法は特権方法と呼ばれています.彼を対外インターフェースと呼ぶのがもっと好きです.
    特権の方法は特に注意しなければならないのは、全体の方法の私有メンバーを保証するために、全体の方法に対する引用に戻さないでください.このように外部も気軽にこの引用を通じてすべての私有メンバーを訪問することができます.これはすべての私有性がありません.
    リアルタイム関数
    上のコードでは、簡単なモジュール棚を持ち上げましたが、通常のシーンでは、いくつかの問題が発生します.実例は以下の通りです.
    ```javascript		
    
                    //        
    
    		var GLOBAL = GLOBAL || {};
    
    		//         
    
    		GLOBAL.namespace = function(str) {
    
    			var arr = str.split("."),
    
    				o = GLOBAL,
                    i; for (i = (arr[0] == "GLOBAL") ? 1 : 0; i < arr.length; i++) { o[arr[i]] = o[arr[i]] || {}; o = o[arr[i]]; } } // GLOBAL.namespace("Module"); // GLOBAL.Module.console = { msg : "WeiRan", log : function(){ console.log(this.msg); } } GLOBAL.Module.console.log(); //WeiRan console.log(GLOBAL.Module.console.msg); //WeiRan // GLOBAL.Module.console1 = (function(){ var msg = "WeiRan"; return{ log : function(){ console.log(msg); } } }()); GLOBAL.Module.console1.log(); //WeiRan console.log(GLOBAL.Module.console1.msg); //undefined ```
    上記では2つのモジュールを列挙しましたが、最初の字面量の形式は完全にプライベート属性を保証できません.彼の全員は公開されています.2番目に、私たちはインスタント関数によって提供されたプライベート・スコープを通じてモジュールのプライベートメンバのプライベート性を保証しています.
    戻ってきたオブジェクトに対しても、共通APIの具体的な実装ロジックがプライベートである場合、開示モジュールモードを使用するのが最適である.
    モジュールモードを表示
    モジュールモードはモジュールモードにおける私有性保護のアップグレードであり、私の以前のセグメントコードを例にとって、詳細コードは以下の通りである.
    ```javascript
    
    	GLOBAL.comm.comnav = (function() {
    
    		var bindNav = function(navList) {
    
    			$.each(navList, function(key, val) {
    
    				$("#" + val.split("-")[0] + ">span").click(function() {
    
    					$(this).siblings().each(function() {
    
    						$(this).find(".active").hide().siblings().find("[_tag=" + $(this).attr("_tag") + "]").removeClass("red");
    
    					});
    
    					$(this).find(".active").show().siblings().find("[_tag=" + $(this).attr("_tag") + "]").addClass("red");
    
    					showTag([val.split("-")[1], val.split("-")[2]], $(this).attr("_tag"));
    
    				});
    
    			});
    
    		};
    
    		var processNav = function(navId, commId, listId) {
    
    			return navId + "-" + commId + "-" + listId;
    
    		};
    
    		var showTag = function(tagList, tagName) {
    
    			$.each(tagList, function(index) {
    
    				$("#" + tagList[index]).find("[_tag=" + tagName + "]").show().siblings().hide();
    
    			});
    
    		};
    
    		return {
    
    			init: bindNav,
    
    			newInstantce: processNav
    
    		}
    
    	})();
    
    ```
    
    
    上記の例では、3つのプライベート方法(関数式で定義されていることに注意してください)をモジュール内部で定義しました.API関数の具体的な論理明示式をリターンの対象に書いていませんでした.私はプライベート方法のAPI関数に対して函数名で伝達しました.このようにモジュール露出のAPI方法まで処理しました.これでこそ本当のインターフェースです.
    おわりに
    最近仕事とお正月の関係で、長い間中断しました.自分も怠けていたことを自覚しました.新しい年が始まりました.また多くのものが私を待って勉強しています.2014年は一字でした.
    もしあなたが文の中で誤りを発見したら、あるいは正しくないと思うところを指摘してください.