JavaScript閉パッケージ(モジュール)とは?


語彙環境の組合せ
オーバーラップ関数では,内部関数が外部関数を記憶する環境をcloserと呼ぶ.
関数が属するコンテキスト範囲を記憶し、関数がその範囲外で実行されたときにアクセスできる機能と見なすことができます.
JavaScriptのスキャン定義によると、関数に宣言された変数は関数外にアクセスできません.ただし、関数で宣言された別の関数からアクセスすることは可能です.
すなわち,内部のサブ関数では,親関数のscope内の変数にアクセスでき,親関数が呼び出しを完了して返されてもアクセスできる.
親関数の情報が実行コンテキストキューから消えても、子関数がまだ存在する場合は、実行を終了した親関数のコンテキスト情報を参照できます.
例1
function func() {
    var foo = 'data';
    return function() {
        return foo;
    }
}

var closure = func();
console.log(closure()); // data
funcの領域変数であるfooはfunc関数の終了とともに消えるべきであるが,出力は「data」であることがわかる.この現象を積み木と呼ぶ.
例2
function count() {
    var num = 0;
    return function() {
        num++;
        return num;
    }
}

var closure = count();
console.log(closure()); // 1
console.log(closure()); // 2
console.log(closure()); // 3
count関数の領域変数num値が消えず、プラス記号が続くことがわかります.
useState
実際,関数型素子上で状態管理を行うためには,関数が再呼び出されたときに以前の状態を記憶する必要があり,反フックのuseStateはキャビネットを介してこの問題を解決する.
const useState = (initialVal) => {
	let innerState = initialVal;
  const state = () => innerState;
  const setState = (newVal) => {
    innerState = newVal;
  }
  return [state, setState];
}
useState関数が実行されると、入力されたinitialValは内部状態に割り当てられ、呼び出しstateは内部stateに戻り、呼び出しsetStateは新しいパラメータに戻ったnewValは内部状態に割り当てられる.
実際には、stateおよびsetStateを使用する時点はuseState呼び出しが終了した後であるが、モジュールはinnerStateの値を記憶しているので、後でアクセスすることもできる.
隠匿化
モジュールは、モジュールモードと呼ばれるオブジェクト向けプログラミングのプライベートメソッドを模倣するために使用することができる.
モジュールモードについては,次の記事でさらに議論する.
各モジュールは、互いの変数に影響を与えることなく、異なるバージョンの変数を参照します.
これにより,モジュールを用いてオブジェクト向けプログラミングの情報隠蔽やパッケージングなどの利点を得ることができる.
JavaScriptでは、インスタンスの作成時にPrivate変数へのアクセス権に問題があります.
function CreateKey(key) {
    this._key = key;
}

var obj = new CreateKey('mykey');
console.log(obj._key); // myKey

obj._key = 'yourKey';
console.log(obj._key); // yourKey
変数名の前に_が含まれているため、Private変数として使用する場合があります.
意図とは異なり、_keyのプロパティは動的に変更できます.
エンクロージャを使用する場合は、外部からの内部変数へのアクセスを制限できます.
function ClosureKey(key) {
    var _key = key;
    return function() {
        console.log(_key);
    }
}

var closureObj = ClosureKey('newKey');
closureObj(); // newKey
console.log(closureObj._key); // undefined
これによりcloserを用いて隠匿化を実現できる.