コンセプト:JavaScript モジュールのデザインパターン
スコープの競合
JavaScript では、var
要素を使用して変数を定義すると、その変数が定義されている関数内でスコープが設定されます。を使用せずに変数を定義するとvar
、グローバルスコープが割り当てられます。つまり、グローバル変数はページ上の他のスクリプトとの衝突に対して脆弱です。
コード例を見てみましょう。次のコードでは、関数と変数はページのスコープ内に存在します。
// script 1
var incrementCount = function() {
count++;
}
var myButton = document.getElementById('buttonId');
var count = 0;
myButton.onclick = incrementCount;
ここで、スクリプトの外部に、count
グローバル変数も変更する関数があるとします。このスクリプトの衝突は、予期しない結果を引き起こす可能性があります。
// script 2
var countVideos = function(videoList) {
count = videoList.length;
}
結果:
myButton
ユーザーがボタンを 2 回選択して、count
変数をインクリメントします。script 1
。count
= 2
countvideos
関数が呼び出されScript 2
、Web ページにも存在します。に 10videoList
個の項目が含まれているとしましょう。これで、count
グローバル変数の値は 10になります。count
= 10
myButton
ユーザーが次にボタンを選択すると、count
変数は予期しない結果を返します。- 期待:
count
= 3 - 実績:
count
= 11
- 期待:
スクリプトの競合を回避しようとするかもしれませんが、ページに含まれているサードパーティスクリプトが同様の関数や変数名を使用しないという保証はありません。
無名関数
1つの解決策は、コードを無名関数 (クロージャとも呼ばれる) でラップし、すぐに実行することです。クロージャ内のコードは、他のスクリプトからはアクセスできません。だから、これはあなたにプライベート関数と変数を作成する方法を提供します。
無名関数の構文は次のとおりです。
- 3行目:関数の呼び出しを待つ代わりに、それが解析された直後に関数を実行するようにJavaScriptに指示する括弧の追加のセットが含まれています。
(function () {
// your code
}());
クロージャは、アプリケーションのライフタイムを通じてプライバシーと状態を提供するため、強力です。クロージャ内のコードの場合、すべての変数と関数はクロージャスコープにのみ含まれます。しかし、クロージャ内のコードはまだグローバル変数や関数にアクセスできます。
グローバル
JavaScript には暗黙グローバルと呼ばれる機能がありますが、どの変数がグローバルであるかを判断することは容易ではないため、コードの管理が難しくなる可能性があります。変数がグローバルかどうかを判断するには、インタプリタはスコープチェーンを後方に歩き、var
名前に一致するステートメントを探す必要があります。何も見つからない場合、変数はグローバルであるとみなされます。
グローバルに渡す
無名関数を使用すると、グローバルパラメータを明示的に渡すことができます。これは、コードへのパラメータのインポートと呼ばれます。
ここに例があります:
- 1 行目:関数に渡されるパラメータの名前を定義します。3 行目の名前と一致する必要がないことに注意してください。ここで、
window
オブジェクトはという名前のパラメータに渡されますwindow1
。 - 3 行目:
window
オブジェクトを関数に渡します。
(function( window1, undefined ) {
...
})(window);
渡されるオブジェクトは 1 つしかありませんが、パラメータが 2 つあるため、undefined
の値は未定義になります。
typeof undefined == "undefined"
これは、他の変数が定義されているかどうかを確認する簡単な方法が必要な場合に便利です。
if(variable1 === undefined)
グローバルをエクスポートする
また、無名関数の外部で変数や関数を渡すこともできます。これは、return
値を使用して行うことができます。
ここに例があります:
- 行 1: 無名関数をに割り当てます
BCLS
。この値には任意の値を指定できます。この例では、BCLS(ブライトコーブラーニングサービス)を使用しています。
var BCLS = (function( window1, undefined ) {
var object1 = {};
object1.count = 1;
object1.method = function () {
...
}
return object1;
})(window);
object1
オブジェクトは、2 つのパブリックプロパティ、count
という名前の変数とという名前の関数でグローバルに利用可能になりました。method
。彼らは私たちの無名関数の外部で次のようにアクセスすることができます:
BCLS.object1.count
BCLS.object1.method
完全な例
ここでは、JavaScript モジュールデザインパターンの完全な例をいくつか挙げます。
例1
この例では、モジュールパターンを使用してプライベート変数とパブリック変数と関数を作成する方法を示します。
- プライベート変数:
myvar
,myvar2
- プライベート機能:
fname
,fname2
- パブリック変数:
myvar3
- パブリック関数:
fname3
var BCLS = ( function() {
var myvar = value,
myvar2 = value;
fname = function() {
...
};
fname2 = function() {
...
};
return {
fname3 : function() {
...
},
myvar3 = value;
};
}());
例2
この例では、グローバルオブジェクトを渡し、パブリック関数を公開します。
var BCLS = (function( window, document, videojs ) {
var myvar = value;
// use a global object passed into the anonymous function
videojs.registerPlugin('overlay');
fname = function() {
...
}
return {
fname2 : function() {
...
}
}
})(window, document, videojs);
// call the public function fname2
var newvar = BCLS.fname2();
コードサンプル
一部のコード例では、JavaScript モジュールデザインパターンを使用し、このパターンの実装方法に関するアイデアを確認することができます。