[Javascript]Closureによるデータ操作とパッケージング
25525 ワード
グローバル変数を使用する場合は?
let Rollover = {}
$(function(){
Rollover.fdno = null
Rollover.bskno = null
Rollover.currst = null
injectObj(Rollover,{
callBskMstByFdidAndCurrst,
callPositionList,
callRollover,
clearSelectedBsk
})
})
→オブジェクトをグローバル変数として宣言し、InjectObject(オブジェクト割り当てカスタマイズ)を使用して関数と変数を処理する→対応する画像のように、ブラウザ開発ツールで簡単にデータを変更できる
Closureを理解する前に、語彙scopeを理解してください.
:語彙scopeとは、ソースコードで宣言された変数を考慮して、変数がどこで使用可能かを知る語彙範囲の定義です.
→簡単に言えば、これは変数のライフサイクルを考えることを意味する(私の観点)
function init() {
var name = "blockjjam"; // name is a local variable created by init
function displayName() { // displayName() is the inner function, a closure
alert (name); // displayName() uses variable declared in the parent function
}
displayName();
}
init();
// init()의 name의 scope는 init함수 안에서만 생존
では、露出とは何ですか.
:これは、一部のデータを操作データの関数に関連付ける有用な技術です.
:関数と関数宣言の語彙環境の組み合わせによるデータの制御
function makeFunc() {
var name = "blockjjam"; (3)
function displayName() {
alert(name);
}
return displayName;
}
var myFunc = makeFunc(); // (1)
//myFunc변수에 displayName을 리턴함
//유효범위의 어휘적 환경을 유지
myFunc(); // (2)
//리턴된 displayName 함수를 실행(name 변수에 접근)
→例により、(1)myFuncはmakeFunc()であり,displayName関数は戻り閉パケットを形成する.
(2)myFunc()を実行するたびにmakeFunc()のscopeにアクセスしdisplayName関数を実行する
→displayName makeFunc関数のnameのみ参照!(モジュール作成時のみname参照)
(3) myFunc.makeFunc()のname変数をnameで変更できますか?
→実行できません!makeFunc()scopeで返されるdisplayName関数以外はアクセスできません(情報を非表示)
Closureでprivateメソッドを模倣する
var counter = (function() {
var privateCounter = 0;
function changeBy(val) {
privateCounter += val;
}
return {
increment: function() {
changeBy(1);
},
decrement: function() {
changeBy(-1);
},
value: function() {
return privateCounter;
}
};
})();
console.log(counter.value()); // logs 0
counter.increment();
counter.increment();
console.log(counter.value()); // logs 2
counter.decrement();
console.log(counter.value()); // logs 1
→上記の例ではcounterを使用してprivateCounter変数に直接アクセスできないため、返されるvalue関数でprivateCounter値を決定できます.私たちは露出で外部データの漏洩を阻止します。
サンプル環境のコピー
例のClosureコードを見てみましょう
var tmp_bskMst = null;
var Rollover = (function(){
let fdno = null
let bskno = null
let currst = null
let bskMstList = null
/** Async Process **/
function callBskMstByFdidAndCurrst(){
clearSelectedBsk()
setCurrst($("#sel_currst").val())
//...
}
function callPositionList(idx){
setFdno(bskMstList[idx].fdno)
setBskno(bskMstList[idx].bskno)
let url = '/order/rollover/list'
let params = createAsyncJsonParam({fdno, bskno, state: currst})
//...
}
function callRollover(){
let url = '/order/rollover/toflask' // 명명법 수정 필요
let params = createAsyncJsonParam({fdno, bskno, state:currst})
//...
}
/** End Async Process **/
/** Util **/
function clearSelectedBsk(){
setFdno(null)
setBskno(null)
setCurrst(null)
setBskMstList(null)
}
const setFdno = (input_fdno)=>{
fdno = input_fdno === null? null : parseInt(input_fdno)
}
const setBskno = (input_bskno)=>{
bskno = input_bskno === null? null : parseInt(input_bskno)
}
const setCurrst = (input_currst)=>{
currst= input_currst === null? null : input_currst;
}
const setBskMstList = (input_bskMstList)=>{
bskMstList = input_bskMstList === null? null : input_bskMstList.slice();
}
/** End Util **/
return {
callBskMstByFdidAndCurrst: callBskMstByFdidAndCurrst,
callPositionList: callPositionList,
callRollover: callRollover,
clearSelectedBsk: clearSelectedBsk
}
})();
let OrderHistory = {}
$(function (){
OrderHistory.fdno = null;
OrderHistory.bskno = null;
OrderHistory.date = null;
// 선언한 객체에 함수 객체를 주입해서 사용
injectObj(OrderHistory, {callFindBskInfo})
injectObj(OrderHistory, {setOneBskInfo})
injectObj(OrderHistory, {callFindBskInfo})
// 페이지 로드 시 Order History에 필요한 설정 정보 clear
OrderHistory.clearSelectedBskInfo()
})
fdno、date、bsknoは、実際にデータを変更した場合にアクセスできます.
外部からオブジェクトにアクセスするだけでデータを制御でき、APIサーバにデータを転送することもできますか?
開発者ツールで扱うように、APIサーバへのデータ転送を確認できます
ここにも近い財産がありますか?そう言えるけど.
CallBskMstByFdidAndCurrst、CallPositionList、CallRollover、clearSelection→これらのプログラムはCloseで暴露できる関数です
var tmp_bskMst = null;
var Rollover = (function(){
//...
return {
callBskMstByFdidAndCurrst: callBskMstByFdidAndCurrst,
callPositionList: callPositionList,
callRollover: callRollover,
clearSelectedBsk: clearSelectedBsk
}
})();
上のコードから見ると、Rollover Closerは露出可能な変数のみを返し、外部からアクセス可能な属性のみを提供します.上の画像から見ると、
1つ目は、Rolloverにアクセスできないbskno、fdno、currstなどの変数です.
2回目の試みでは、RolloverのProperty割り当てと外部に露出した関数の実行を強制します.
上の結果画像を表示します.
APIサーバにアクセスしていないため、デバッグ画面もキャプチャされていません.
(フルスクリーンでは公開できませんが)スクリプトに値情報が正しく含まれていないことがわかります
:エンクロージャを使用すると、露出可能データと非露出データを区別でき、データをカプセル化できます.
:キャビネットの注意事項として、露出したデータの実現と管理が重要だと思います
理由は?グローバル変数でもモジュールでも、実際には、開発者の意図通りに処理するだけであれば問題はなく、逆に非開発者の意図的なアクセスには問題が多い.
→エンクロージャにおいても、露出データの入力値においても、操作外部データ(tagの属性値など)は検証が必要
Reference
この問題について([Javascript]Closureによるデータ操作とパッケージング), 我々は、より多くの情報をここで見つけました https://velog.io/@blockjjam/Javascript-Closure를-통해-데이터-조작과-캡슐화를-가능하게-해보자テキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol