JavaScript ํ๋ก์ ํธ๋ค๋ฌ๋ฅผ ์ฌ์ฉํ์ฌ ํ๋ผ์ด๋น ํ๋๋ฅผ ์๋ฎฌ๋ ์ด์ ํ๊ณ ๊ฐ์ ํ์ฌ ์บก์ํ์ ์ฝ๋ ์ ์ง๋ณด์์ฑ์ ํฅ์์ํค๋ ๋ฐฉ๋ฒ์ ์์๋ณด์ธ์.
JavaScript ํ๋ผ์ด๋น ํ๋ ํ๋ก์ ํธ๋ค๋ฌ: ์บก์ํ ๊ฐ์ ํ๊ธฐ
๊ฐ์ฒด ์งํฅ ํ๋ก๊ทธ๋๋ฐ์ ํต์ฌ ์์น์ธ ์บก์ํ๋ ๋ฐ์ดํฐ(์์ฑ)์ ํด๋น ๋ฐ์ดํฐ์ ๋ํด ์๋ํ๋ ๋ฉ์๋๋ฅผ ๋จ์ผ ๋จ์(ํด๋์ค ๋๋ ๊ฐ์ฒด) ๋ด์ ๋ฌถ๊ณ , ๊ฐ์ฒด์ ์ผ๋ถ ๊ตฌ์ฑ ์์์ ๋ํ ์ง์ ์ ์ธ ์ ๊ทผ์ ์ ํํ๋ ๊ฒ์ ๋ชฉํ๋ก ํฉ๋๋ค. JavaScript๋ ์ด๋ฅผ ๋ฌ์ฑํ๊ธฐ ์ํ ๋ค์ํ ๋ฉ์ปค๋์ฆ์ ์ ๊ณตํ์ง๋ง, ์ต๊ทผ ECMAScript ๋ฒ์ ์ # ๊ตฌ๋ฌธ์ด ๋์
๋๊ธฐ ์ ๊น์ง๋ ์ ํต์ ์ผ๋ก ์ง์ ํ ํ๋ผ์ด๋น ํ๋๊ฐ ๋ถ์กฑํ์ต๋๋ค. ๊ทธ๋ฌ๋ # ๊ตฌ๋ฌธ์ ํจ๊ณผ์ ์ด๊ธด ํ์ง๋ง ๋ชจ๋ JavaScript ํ๊ฒฝ๊ณผ ์ฝ๋๋ฒ ์ด์ค์์ ๋ณดํธ์ ์ผ๋ก ์ฑํ๋๊ณ ์ดํด๋์ง๋ ์์ต๋๋ค. ์ด ๊ธ์์๋ JavaScript ํ๋ก์ ํธ๋ค๋ฌ๋ฅผ ์ฌ์ฉํ์ฌ ์บก์ํ๋ฅผ ๊ฐ์ ํ๋ ๋์์ ์ธ ์ ๊ทผ ๋ฐฉ์์ ํ์ํ๋ฉฐ, ํ๋ผ์ด๋น ํ๋๋ฅผ ์๋ฎฌ๋ ์ด์
ํ๊ณ ๊ฐ์ฒด ์์ฑ์ ๋ํ ์ ๊ทผ์ ์ ์ดํ๋ ์ ์ฐํ๊ณ ๊ฐ๋ ฅํ ๊ธฐ์ ์ ์ ๊ณตํฉ๋๋ค.
ํ๋ผ์ด๋น ํ๋์ ํ์์ฑ ์ดํดํ๊ธฐ
๊ตฌํ์ ๋ํด ์์ธํ ์์๋ณด๊ธฐ ์ ์, ํ๋ผ์ด๋น ํ๋๊ฐ ์ ์ค์ํ์ง ์ดํดํด ๋ด ์๋ค:
- ๋ฐ์ดํฐ ๋ฌด๊ฒฐ์ฑ: ์ธ๋ถ ์ฝ๋๊ฐ ๋ด๋ถ ์ํ๋ฅผ ์ง์ ์์ ํ๋ ๊ฒ์ ๋ฐฉ์งํ์ฌ ๋ฐ์ดํฐ์ ์ผ๊ด์ฑ๊ณผ ์ ํจ์ฑ์ ๋ณด์ฅํฉ๋๋ค.
- ์ฝ๋ ์ ์ง๋ณด์์ฑ: ๊ฐ๋ฐ์๊ฐ ๊ฐ์ฒด์ ๊ณต๊ฐ ์ธํฐํ์ด์ค์ ์์กดํ๋ ์ธ๋ถ ์ฝ๋์ ์ํฅ์ ์ฃผ์ง ์๊ณ ๋ด๋ถ ๊ตฌํ ์ธ๋ถ ์ ๋ณด๋ฅผ ๋ฆฌํฉํฐ๋งํ ์ ์๋๋ก ํฉ๋๋ค.
- ์ถ์ํ: ๋ณต์กํ ๊ตฌํ ์ธ๋ถ ์ ๋ณด๋ฅผ ์จ๊ธฐ๊ณ ๊ฐ์ฒด์ ์ํธ ์์ฉํ๊ธฐ ์ํ ๋จ์ํ๋ ์ธํฐํ์ด์ค๋ฅผ ์ ๊ณตํฉ๋๋ค.
- ๋ณด์: ๋ฏผ๊ฐํ ๋ฐ์ดํฐ์ ๋ํ ์ ๊ทผ์ ์ ํํ์ฌ ๋ฌด๋จ ์์ ์ด๋ ๊ณต๊ฐ๋ฅผ ๋ฐฉ์งํฉ๋๋ค. ์ด๋ ์ฌ์ฉ์ ๋ฐ์ดํฐ, ๊ธ์ต ์ ๋ณด ๋๋ ๊ธฐํ ์ค์ํ ๋ฆฌ์์ค๋ฅผ ๋ค๋ฃฐ ๋ ํนํ ์ค์ํฉ๋๋ค.
์์ฑ ์์ ๋ฐ์ค(_)์ ๋ถ์ด๋ ๊ฒ๊ณผ ๊ฐ์ ๊ด๋ก๊ฐ ํ๋ผ์ด๋น์ ์๋ํจ์ ๋ํ๋ด๊ธฐ ์ํด ์กด์ฌํ์ง๋ง, ์ด๋ฅผ ๊ฐ์ ํ์ง๋ ์์ต๋๋ค. ๊ทธ๋ฌ๋ ํ๋ก์ ํธ๋ค๋ฌ๋ ์ง์ ๋ ์์ฑ์ ๋ํ ์ ๊ทผ์ ์ ๊ทน์ ์ผ๋ก ๋ฐฉ์งํ์ฌ ์ง์ ํ ํ๋ผ์ด๋ฒ์๋ฅผ ๋ชจ๋ฐฉํ ์ ์์ต๋๋ค.
JavaScript ํ๋ก์ ํธ๋ค๋ฌ ์๊ฐ
JavaScript ํ๋ก์ ํธ๋ค๋ฌ๋ ๊ฐ์ฒด์ ๋ํ ๊ธฐ๋ณธ์ ์ธ ์์ ์ ๊ฐ๋ก์ฑ๊ณ ์ฌ์ฉ์ ์ ์ํ ์ ์๋ ๊ฐ๋ ฅํ ๋ฉ์ปค๋์ฆ์ ์ ๊ณตํฉ๋๋ค. ํ๋ก์ ๊ฐ์ฒด๋ ๋ค๋ฅธ ๊ฐ์ฒด(๋์)๋ฅผ ๊ฐ์ธ๊ณ ์์ฑ์ ๊ฐ์ ธ์ค๊ฑฐ๋, ์ค์ ํ๊ฑฐ๋, ์ญ์ ํ๋ ๋ฑ์ ์์ ์ ๊ฐ๋ก์ฑ๋๋ค. ์ด ๋์์ ์ด๋ฌํ ์์ ์ด ๋ฐ์ํ ๋ ํธ์ถ๋๋ ๋ฉ์๋(ํธ๋ฉ)๋ฅผ ํฌํจํ๋ ํธ๋ค๋ฌ ๊ฐ์ฒด์ ์ํด ์ ์๋ฉ๋๋ค.
์ฃผ์ ๊ฐ๋ :
- ๋์(Target): ํ๋ก์๊ฐ ๊ฐ์ธ๋ ์๋ณธ ๊ฐ์ฒด์ ๋๋ค.
- ํธ๋ค๋ฌ(Handler): ํ๋ก์์ ๋์์ ์ ์ํ๋ ๋ฉ์๋(ํธ๋ฉ)๋ฅผ ํฌํจํ๋ ๊ฐ์ฒด์ ๋๋ค.
- ํธ๋ฉ(Traps): ๋์ ๊ฐ์ฒด์ ๋ํ ์์
์ ๊ฐ๋ก์ฑ๋ ํธ๋ค๋ฌ ๋ด์ ๋ฉ์๋์
๋๋ค. ์๋ก๋
get,set,has,deleteProperty,apply๊ฐ ์์ต๋๋ค.
ํ๋ก์ ํธ๋ค๋ฌ๋ก ํ๋ผ์ด๋น ํ๋ ๊ตฌํํ๊ธฐ
ํต์ฌ ์์ด๋์ด๋ ํ๋ก์ ํธ๋ค๋ฌ์ get ๋ฐ set ํธ๋ฉ์ ์ฌ์ฉํ์ฌ ํ๋ผ์ด๋น ํ๋์ ์ ๊ทผํ๋ ค๋ ์๋๋ฅผ ๊ฐ๋ก์ฑ๋ ๊ฒ์
๋๋ค. ํ๋ผ์ด๋น ํ๋๋ฅผ ์๋ณํ๊ธฐ ์ํ ๊ด๋ก(์: ๋ฐ์ค๋ก ์์ํ๋ ์์ฑ)๋ฅผ ์ ์ํ ๋ค์ ๊ฐ์ฒด ์ธ๋ถ์์์ ์ ๊ทผ์ ๋ง์ ์ ์์ต๋๋ค.
๊ตฌํ ์์
BankAccount ํด๋์ค๋ฅผ ์๊ฐํด ๋ด
์๋ค. _balance ์์ฑ์ด ์ธ๋ถ์์ ์ง์ ์์ ๋๋ ๊ฒ์ ๋ณดํธํ๊ณ ์ถ์ต๋๋ค. ํ๋ก์ ํธ๋ค๋ฌ๋ฅผ ์ฌ์ฉํ์ฌ ์ด๋ฅผ ๋ฌ์ฑํ๋ ๋ฐฉ๋ฒ์ ๋ค์๊ณผ ๊ฐ์ต๋๋ค:
class BankAccount {
constructor(accountNumber, initialBalance) {
this.accountNumber = accountNumber;
this._balance = initialBalance; // ๋น๊ณต๊ฐ ์์ฑ (๊ด๋ก)
}
deposit(amount) {
this._balance += amount;
return this._balance;
}
withdraw(amount) {
if (amount <= this._balance) {
this._balance -= amount;
return this._balance;
} else {
throw new Error("Insufficient funds.");
}
}
getBalance() {
return this._balance; // ์์ก์ ์ ๊ทผํ๋ ๊ณต๊ฐ ๋ฉ์๋
}
}
function createBankAccountProxy(bankAccount) {
const privateFields = ['_balance'];
const handler = {
get: function(target, prop, receiver) {
if (privateFields.includes(prop)) {
// ํด๋์ค ๋ด๋ถ์์์ ์ ๊ทผ์ธ์ง ํ์ธ
if (target === receiver) {
return target[prop]; // ํด๋์ค ๋ด์์์ ์ ๊ทผ ํ์ฉ
}
throw new Error(`Cannot access private property '${prop}'.`);
}
return Reflect.get(...arguments);
},
set: function(target, prop, value) {
if (privateFields.includes(prop)) {
throw new Error(`Cannot set private property '${prop}'.`);
}
return Reflect.set(...arguments);
}
};
return new Proxy(bankAccount, handler);
}
// ์ฌ์ฉ๋ฒ
const account = new BankAccount("1234567890", 1000);
const proxiedAccount = createBankAccountProxy(account);
console.log(proxiedAccount.accountNumber); // ์ ๊ทผ ํ์ฉ (๊ณต๊ฐ ์์ฑ)
console.log(proxiedAccount.getBalance()); // ์ ๊ทผ ํ์ฉ (๋ด๋ถ์ ์ผ๋ก ๋น๊ณต๊ฐ ์์ฑ์ ์ ๊ทผํ๋ ๊ณต๊ฐ ๋ฉ์๋)
// ๋น๊ณต๊ฐ ํ๋์ ์ง์ ์ ๊ทผํ๊ฑฐ๋ ์์ ํ๋ ค๊ณ ์๋ํ๋ฉด ์ค๋ฅ๊ฐ ๋ฐ์ํฉ๋๋ค
try {
console.log(proxiedAccount._balance); // ์ค๋ฅ ๋ฐ์
} catch (error) {
console.error(error.message);
}
try {
proxiedAccount._balance = 500; // ์ค๋ฅ ๋ฐ์
} catch (error) {
console.error(error.message);
}
console.log(account.getBalance()); // ๋ด๋ถ ๋ฉ์๋๊ฐ ์ ๊ทผ ๊ถํ์ด ์์ผ๋ฏ๋ก ์ค์ ์์ก์ ์ถ๋ ฅํฉ๋๋ค.
// ๊ฐ์ฒด ๋ด๋ถ์์ ๋น๊ณต๊ฐ ์์ฑ์ ์ ๊ทผํ๊ธฐ ๋๋ฌธ์ ์๋ํ๋ ์
๊ธ ๋ฐ ์ถ๊ธ ์์ฐ์
๋๋ค.
console.log(proxiedAccount.deposit(500)); // 500 ์
๊ธ
console.log(proxiedAccount.withdraw(200)); // 200 ์ถ๊ธ
console.log(proxiedAccount.getBalance()); // ์ ํํ ์์ก ํ์
์ค๋ช
BankAccountํด๋์ค: ๊ณ์ข ๋ฒํธ์ ๋น๊ณต๊ฐ_balance์์ฑ(๋ฐ์ค ๊ด๋ก ์ฌ์ฉ)์ ์ ์ํฉ๋๋ค. ์ ๊ธ, ์ถ๊ธ ๋ฐ ์์ก ์กฐํ ๋ฉ์๋๋ฅผ ํฌํจํฉ๋๋ค.createBankAccountProxyํจ์:BankAccount๊ฐ์ฒด์ ๋ํ ํ๋ก์๋ฅผ ์์ฑํฉ๋๋ค.privateFields๋ฐฐ์ด: ๋น๊ณต๊ฐ๋ก ๊ฐ์ฃผ๋์ด์ผ ํ ์์ฑ์ ์ด๋ฆ์ ์ ์ฅํฉ๋๋ค.handler๊ฐ์ฒด:get๋ฐsetํธ๋ฉ์ ํฌํจํฉ๋๋ค.getํธ๋ฉ:- ์ ๊ทผ๋ ์์ฑ(
prop)์ดprivateFields๋ฐฐ์ด์ ์๋์ง ํ์ธํฉ๋๋ค. - ํ๋ผ์ด๋น ํ๋์ธ ๊ฒฝ์ฐ ์ค๋ฅ๋ฅผ ๋ฐ์์์ผ ์ธ๋ถ ์ ๊ทผ์ ๋ฐฉ์งํฉ๋๋ค.
- ํ๋ผ์ด๋น ํ๋๊ฐ ์๋ ๊ฒฝ์ฐ
Reflect.get์ ์ฌ์ฉํ์ฌ ๊ธฐ๋ณธ ์์ฑ ์ ๊ทผ์ ์ํํฉ๋๋ค. ์ด์ target === receiverํ์ธ์ ์ ๊ทผ์ด ๋์ ๊ฐ์ฒด ์์ฒด ๋ด์์ ์์๋์๋์ง ์ฌ๋ถ๋ฅผ ๊ฒ์ฆํฉ๋๋ค. ๊ทธ๋ ๋ค๋ฉด ์ ๊ทผ์ ํ์ฉํฉ๋๋ค.
- ์ ๊ทผ๋ ์์ฑ(
setํธ๋ฉ:- ์ค์ ๋๋ ์์ฑ(
prop)์ดprivateFields๋ฐฐ์ด์ ์๋์ง ํ์ธํฉ๋๋ค. - ํ๋ผ์ด๋น ํ๋์ธ ๊ฒฝ์ฐ ์ค๋ฅ๋ฅผ ๋ฐ์์์ผ ์ธ๋ถ ์์ ์ ๋ฐฉ์งํฉ๋๋ค.
- ํ๋ผ์ด๋น ํ๋๊ฐ ์๋ ๊ฒฝ์ฐ
Reflect.set์ ์ฌ์ฉํ์ฌ ๊ธฐ๋ณธ ์์ฑ ํ ๋น์ ์ํํฉ๋๋ค.
- ์ค์ ๋๋ ์์ฑ(
- ์ฌ์ฉ๋ฒ:
BankAccount๊ฐ์ฒด๋ฅผ ์์ฑํ๊ณ ํ๋ก์๋ก ๊ฐ์ผ ๋ค์ ์์ฑ์ ์ ๊ทผํ๋ ๋ฐฉ๋ฒ์ ๋ณด์ฌ์ค๋๋ค. ๋ํ ํด๋์ค ์ธ๋ถ์์ ๋น๊ณต๊ฐ_balance์์ฑ์ ์ ๊ทผํ๋ ค๊ณ ํ๋ฉด ์ค๋ฅ๊ฐ ๋ฐ์ํ์ฌ ํ๋ผ์ด๋ฒ์๊ฐ ๊ฐ์ ๋๋ ๊ฒ์ ๋ณด์ฌ์ค๋๋ค. ๊ฒฐ์ ์ ์ผ๋ก, ํด๋์ค *๋ด๋ถ*์getBalance()๋ฉ์๋๋ ๊ณ์ํด์ ์ฌ๋ฐ๋ฅด๊ฒ ์๋ํ๋ฉฐ, ์ด๋ ๋น๊ณต๊ฐ ์์ฑ์ด ํด๋์ค์ ๋ฒ์ ๋ด์์๋ ์ฌ์ ํ ์ ๊ทผ ๊ฐ๋ฅํ๋ค๋ ๊ฒ์ ๋ณด์ฌ์ค๋๋ค.
๊ณ ๊ธ ๊ณ ๋ ค์ฌํญ
์ง์ ํ ํ๋ผ์ด๋ฒ์๋ฅผ ์ํ WeakMap
์ด์ ์์ ๋ ํ๋ผ์ด๋น ํ๋๋ฅผ ์๋ณํ๊ธฐ ์ํด ๋ช
๋ช
๊ท์น(๋ฐ์ค ์ ๋์ฌ)์ ์ฌ์ฉํ์ง๋ง, ๋ ๊ฒฌ๊ณ ํ ์ ๊ทผ ๋ฐฉ์์ WeakMap์ ์ฌ์ฉํ๋ ๊ฒ์
๋๋ค. WeakMap์ ์ฌ์ฉํ๋ฉด ๊ฐ์ฒด๊ฐ ๊ฐ๋น์ง ์ปฌ๋ ์
๋๋ ๊ฒ์ ๋ง์ง ์์ผ๋ฉด์ ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ฒด์ ์ฐ๊ฒฐํ ์ ์์ต๋๋ค. ์ด๋ ๋ฐ์ดํฐ๊ฐ WeakMap์ ํตํด์๋ง ์ ๊ทผ ๊ฐ๋ฅํ๊ณ , ํค(๊ฐ์ฒด)๊ฐ ๋ ์ด์ ๋ค๋ฅธ ๊ณณ์์ ์ฐธ์กฐ๋์ง ์์ผ๋ฉด ๊ฐ๋น์ง ์ปฌ๋ ์
๋ ์ ์๊ธฐ ๋๋ฌธ์ ์ง์ ์ผ๋ก ํ๋ผ์ด๋นํ ์ ์ฅ ๋ฉ์ปค๋์ฆ์ ์ ๊ณตํฉ๋๋ค.
const privateData = new WeakMap();
class BankAccount {
constructor(accountNumber, initialBalance) {
this.accountNumber = accountNumber;
privateData.set(this, { balance: initialBalance }); // WeakMap์ ์์ก ์ ์ฅ
}
deposit(amount) {
const data = privateData.get(this);
data.balance += amount;
privateData.set(this, data); // WeakMap ์
๋ฐ์ดํธ
return data.balance; // weakmap์์ ๋ฐ์ดํฐ ๋ฐํ
}
withdraw(amount) {
const data = privateData.get(this);
if (amount <= data.balance) {
data.balance -= amount;
privateData.set(this, data);
return data.balance;
} else {
throw new Error("Insufficient funds.");
}
}
getBalance() {
const data = privateData.get(this);
return data.balance;
}
}
function createBankAccountProxy(bankAccount) {
const handler = {
get: function(target, prop, receiver) {
if (prop === 'getBalance' || prop === 'deposit' || prop === 'withdraw' || prop === 'accountNumber') {
return Reflect.get(...arguments);
}
throw new Error(`Cannot access public property '${prop}'.`);
},
set: function(target, prop, value) {
throw new Error(`Cannot set public property '${prop}'.`);
}
};
return new Proxy(bankAccount, handler);
}
// ์ฌ์ฉ๋ฒ
const account = new BankAccount("1234567890", 1000);
const proxiedAccount = createBankAccountProxy(account);
console.log(proxiedAccount.accountNumber); // ์ ๊ทผ ํ์ฉ (๊ณต๊ฐ ์์ฑ)
console.log(proxiedAccount.getBalance()); // ์ ๊ทผ ํ์ฉ (๋ด๋ถ์ ์ผ๋ก ๋น๊ณต๊ฐ ์์ฑ์ ์ ๊ทผํ๋ ๊ณต๊ฐ ๋ฉ์๋)
// ๋ค๋ฅธ ์์ฑ์ ์ง์ ์ ๊ทผํ๋ ค๊ณ ํ๋ฉด ์ค๋ฅ๊ฐ ๋ฐ์ํฉ๋๋ค
try {
console.log(proxiedAccount.balance); // ์ค๋ฅ ๋ฐ์
} catch (error) {
console.error(error.message);
}
try {
proxiedAccount.balance = 500; // ์ค๋ฅ ๋ฐ์
} catch (error) {
console.error(error.message);
}
console.log(account.getBalance()); // ๋ด๋ถ ๋ฉ์๋๊ฐ ์ ๊ทผ ๊ถํ์ด ์์ผ๋ฏ๋ก ์ค์ ์์ก์ ์ถ๋ ฅํฉ๋๋ค.
// ๊ฐ์ฒด ๋ด๋ถ์์ ๋น๊ณต๊ฐ ์์ฑ์ ์ ๊ทผํ๊ธฐ ๋๋ฌธ์ ์๋ํ๋ ์
๊ธ ๋ฐ ์ถ๊ธ ์์ฐ์
๋๋ค.
console.log(proxiedAccount.deposit(500)); // 500 ์
๊ธ
console.log(proxiedAccount.withdraw(200)); // 200 ์ถ๊ธ
console.log(proxiedAccount.getBalance()); // ์ ํํ ์์ก ํ์
์ค๋ช
privateData: ๊ฐ BankAccount ์ธ์คํด์ค์ ๋น๊ณต๊ฐ ๋ฐ์ดํฐ๋ฅผ ์ ์ฅํ๊ธฐ ์ํ WeakMap์ ๋๋ค.- ์์ฑ์: BankAccount ์ธ์คํด์ค๋ฅผ ํค๋ก ์ฌ์ฉํ์ฌ ์ด๊ธฐ ์์ก์ WeakMap์ ์ ์ฅํฉ๋๋ค.
deposit,withdraw,getBalance: WeakMap์ ํตํด ์์ก์ ์ ๊ทผํ๊ณ ์์ ํฉ๋๋ค.- ํ๋ก์๋
getBalance,deposit,withdraw๋ฉ์๋์accountNumber์์ฑ์๋ง ์ ๊ทผ์ ํ์ฉํฉ๋๋ค. ๋ค๋ฅธ ๋ชจ๋ ์์ฑ์ ์ค๋ฅ๋ฅผ ๋ฐ์์ํต๋๋ค.
์ด ์ ๊ทผ ๋ฐฉ์์ balance๊ฐ BankAccount ๊ฐ์ฒด์ ์์ฑ์ผ๋ก ์ง์ ์ ๊ทผํ ์ ์๊ณ WeakMap์ ๋ณ๋๋ก ์ ์ฅ๋๊ธฐ ๋๋ฌธ์ ์ง์ ํ ํ๋ผ์ด๋ฒ์๋ฅผ ์ ๊ณตํฉ๋๋ค.
์์ ์ฒ๋ฆฌ
์์์ ๋ค๋ฃฐ ๋ ํ๋ก์ ํธ๋ค๋ฌ๋ ์์ ๊ณ์ธต์ ์ธ์ํด์ผ ํฉ๋๋ค. get ๋ฐ set ํธ๋ฉ์ ์ ๊ทผํ๋ ์์ฑ์ด ๋ถ๋ชจ ํด๋์ค ์ค ํ๋์์ ๋น๊ณต๊ฐ์ธ์ง ํ์ธํด์ผ ํฉ๋๋ค.
๋ค์ ์์ ๋ฅผ ๊ณ ๋ คํด ๋ณด์ธ์:
class BaseClass {
constructor() {
this._privateBaseField = 'Base Value';
}
getPrivateBaseField() {
return this._privateBaseField;
}
}
class DerivedClass extends BaseClass {
constructor() {
super();
this._privateDerivedField = 'Derived Value';
}
getPrivateDerivedField() {
return this._privateDerivedField;
}
}
function createProxy(target) {
const privateFields = ['_privateBaseField', '_privateDerivedField'];
const handler = {
get: function(target, prop, receiver) {
if (privateFields.includes(prop)) {
if (target === receiver) {
return target[prop];
}
throw new Error(`Cannot access private property '${prop}'.`);
}
return Reflect.get(...arguments);
},
set: function(target, prop, value) {
if (privateFields.includes(prop)) {
throw new Error(`Cannot set private property '${prop}'.`);
}
return Reflect.set(...arguments);
}
};
return new Proxy(target, handler);
}
const derivedInstance = new DerivedClass();
const proxiedInstance = createProxy(derivedInstance);
console.log(proxiedInstance.getPrivateBaseField()); // ์๋ํจ
console.log(proxiedInstance.getPrivateDerivedField()); // ์๋ํจ
try {
console.log(proxiedInstance._privateBaseField); // ์ค๋ฅ ๋ฐ์
} catch (error) {
console.error(error.message);
}
try {
console.log(proxiedInstance._privateDerivedField); // ์ค๋ฅ ๋ฐ์
} catch (error) {
console.error(error.message);
}
์ด ์์ ์์ createProxy ํจ์๋ BaseClass์ DerivedClass ๋ชจ๋์ ํ๋ผ์ด๋น ํ๋๋ฅผ ์ธ์ํด์ผ ํฉ๋๋ค. ๋ ์ ๊ตํ ๊ตฌํ์ ๋ชจ๋ ํ๋ผ์ด๋น ํ๋๋ฅผ ์๋ณํ๊ธฐ ์ํด ํ๋กํ ํ์
์ฒด์ธ์ ์ฌ๊ท์ ์ผ๋ก ์ํํ๋ ๊ฒ์ ํฌํจํ ์ ์์ต๋๋ค.
์บก์ํ๋ฅผ ์ํด ํ๋ก์ ํธ๋ค๋ฌ๋ฅผ ์ฌ์ฉํ ๋์ ์ด์
- ์ ์ฐ์ฑ: ํ๋ก์ ํธ๋ค๋ฌ๋ ์์ฑ ์ ๊ทผ์ ๋ํ ์ธ๋ฐํ ์ ์ด๋ฅผ ์ ๊ณตํ์ฌ ๋ณต์กํ ์ ๊ทผ ์ ์ด ๊ท์น์ ๊ตฌํํ ์ ์๊ฒ ํฉ๋๋ค.
- ํธํ์ฑ: ํ๋ก์ ํธ๋ค๋ฌ๋ ํ๋ผ์ด๋น ํ๋๋ฅผ ์ํ
#๊ตฌ๋ฌธ์ ์ง์ํ์ง ์๋ ์ค๋๋ JavaScript ํ๊ฒฝ์์๋ ์ฌ์ฉํ ์ ์์ต๋๋ค. - ํ์ฅ์ฑ: ๋ก๊น
์ด๋ ์ ํจ์ฑ ๊ฒ์ฌ์ ๊ฐ์ ์ถ๊ฐ์ ์ธ ๋ก์ง์
get๋ฐsetํธ๋ฉ์ ์ฝ๊ฒ ์ถ๊ฐํ ์ ์์ต๋๋ค. - ์ฌ์ฉ์ ์ ์ ๊ฐ๋ฅ: ์ ํ๋ฆฌ์ผ์ด์ ์ ํน์ ์๊ตฌ ์ฌํญ์ ์ถฉ์กฑํ๋๋ก ํ๋ก์์ ๋์์ ๋ง์ถค ์ค์ ํ ์ ์์ต๋๋ค.
- ๋น์นจ์ต์ : ๋ค๋ฅธ ์ผ๋ถ ๊ธฐ์ ๊ณผ ๋ฌ๋ฆฌ ํ๋ก์ ํธ๋ค๋ฌ๋ ์๋ณธ ํด๋์ค ์ ์๋ฅผ ์์ ํ ํ์๊ฐ ์์ผ๋ฏ๋ก(WeakMap ๊ตฌํ์ ํด๋์ค์ ์ํฅ์ ๋ฏธ์น์ง๋ง ๊น๋ํ ๋ฐฉ์์ผ๋ก ์ด๋ฃจ์ด์ง) ๊ธฐ์กด ์ฝ๋๋ฒ ์ด์ค์ ํตํฉํ๊ธฐ๊ฐ ๋ ์ฝ์ต๋๋ค.
๋จ์ ๋ฐ ๊ณ ๋ ค์ฌํญ
- ์ฑ๋ฅ ์ค๋ฒํค๋: ํ๋ก์ ํธ๋ค๋ฌ๋ ๋ชจ๋ ์์ฑ ์ ๊ทผ์ ๊ฐ๋ก์ฑ๊ธฐ ๋๋ฌธ์ ์ฑ๋ฅ ์ค๋ฒํค๋๊ฐ ๋ฐ์ํฉ๋๋ค. ์ด ์ค๋ฒํค๋๋ ์ฑ๋ฅ์ด ์ค์ํ ์ ํ๋ฆฌ์ผ์ด์ ์์๋ ์๋นํ ์ ์์ต๋๋ค. ์ด๋ ํนํ ๋จ์ํ ๊ตฌํ์์ ๋๋๋ฌ์ง๋ฏ๋ก ํธ๋ค๋ฌ ์ฝ๋ ์ต์ ํ๊ฐ ์ค์ํฉ๋๋ค.
- ๋ณต์ก์ฑ: ํ๋ก์ ํธ๋ค๋ฌ๋ฅผ ๊ตฌํํ๋ ๊ฒ์
#๊ตฌ๋ฌธ์ด๋ ๋ช ๋ช ๊ท์น์ ์ฌ์ฉํ๋ ๊ฒ๋ณด๋ค ๋ ๋ณต์กํ ์ ์์ต๋๋ค. ์ฌ๋ฐ๋ฅธ ๋์์ ๋ณด์ฅํ๊ธฐ ์ํด ์ ์คํ ์ค๊ณ์ ํ ์คํธ๊ฐ ํ์ํฉ๋๋ค. - ๋๋ฒ๊น : ํ๋ก์ ํธ๋ค๋ฌ๋ฅผ ์ฌ์ฉํ๋ ์ฝ๋๋ ์์ฑ ์ ๊ทผ ๋ก์ง์ด ํธ๋ค๋ฌ ๋ด์ ์จ๊ฒจ์ ธ ์๊ธฐ ๋๋ฌธ์ ๋๋ฒ๊น ํ๊ธฐ ์ด๋ ค์ธ ์ ์์ต๋๋ค.
- ์ธํธ๋ก์คํ์
์ ํ:
Object.keys()๋for...in๋ฃจํ์ ๊ฐ์ ๊ธฐ์ ์ ํ๋ก์์ ํจ๊ป ์๊ธฐ์น ์๊ฒ ๋์ํ ์ ์์ผ๋ฉฐ, ์ง์ ์ ๊ทผํ ์ ์๋๋ผ๋ "ํ๋ผ์ด๋น" ์์ฑ์ ์กด์ฌ๋ฅผ ๋ ธ์ถํ ์ ์์ต๋๋ค. ์ด๋ฌํ ๋ฉ์๋๊ฐ ํ๋ก์๋ ๊ฐ์ฒด์ ์ํธ ์์ฉํ๋ ๋ฐฉ์์ ์ ์ดํ๋ ๋ฐ ์ฃผ์๋ฅผ ๊ธฐ์ธ์ฌ์ผ ํฉ๋๋ค.
ํ๋ก์ ํธ๋ค๋ฌ์ ๋์
- ํ๋ผ์ด๋น ํ๋ (
#๊ตฌ๋ฌธ): ํ๋ JavaScript ํ๊ฒฝ์ ๊ถ์ฅ๋๋ ์ ๊ทผ ๋ฐฉ์์ ๋๋ค. ์ต์ํ์ ์ฑ๋ฅ ์ค๋ฒํค๋๋ก ์ง์ ํ ํ๋ผ์ด๋ฒ์๋ฅผ ์ ๊ณตํฉ๋๋ค. ๊ทธ๋ฌ๋ ์ด๋ ์ค๋๋ ๋ธ๋ผ์ฐ์ ์ ํธํ๋์ง ์์ผ๋ฉฐ ์ค๋๋ ํ๊ฒฝ์์ ์ฌ์ฉํ๋ ค๋ฉด ํธ๋์คํ์ผ๋ง์ด ํ์ํฉ๋๋ค. - ๋ช ๋ช ๊ท์น (๋ฐ์ค ์ ๋์ฌ): ์๋๋ ํ๋ผ์ด๋ฒ์๋ฅผ ๋ํ๋ด๋ ๊ฐ๋จํ๊ณ ๋๋ฆฌ ์ฌ์ฉ๋๋ ๊ด๋ก์ ๋๋ค. ํ๋ผ์ด๋ฒ์๋ฅผ ๊ฐ์ ํ์ง ์๊ณ ๊ฐ๋ฐ์์ ๊ท์จ์ ์์กดํฉ๋๋ค.
- ํด๋ก์ : ํจ์ ๋ฒ์ ๋ด์์ ํ๋ผ์ด๋น ๋ณ์๋ฅผ ๋ง๋๋ ๋ฐ ์ฌ์ฉํ ์ ์์ต๋๋ค. ํฐ ํด๋์ค์ ์์์์๋ ๋ณต์กํด์ง ์ ์์ต๋๋ค.
์ฌ์ฉ ์ฌ๋ก
- ๋ฏผ๊ฐํ ๋ฐ์ดํฐ ๋ณดํธ: ์ฌ์ฉ์ ๋ฐ์ดํฐ, ๊ธ์ต ์ ๋ณด ๋๋ ๊ธฐํ ์ค์ํ ๋ฆฌ์์ค์ ๋ํ ๋ฌด๋จ ์ ๊ทผ ๋ฐฉ์ง.
- ๋ณด์ ์ ์ฑ ๊ตฌํ: ์ฌ์ฉ์ ์ญํ ์ด๋ ๊ถํ์ ๊ธฐ๋ฐํ ์ ๊ทผ ์ ์ด ๊ท์น ๊ฐ์ .
- ์์ฑ ์ ๊ทผ ๋ชจ๋ํฐ๋ง: ๋๋ฒ๊น ์ด๋ ๋ณด์ ๋ชฉ์ ์ผ๋ก ์์ฑ ์ ๊ทผ์ ๋ก๊น ํ๊ฑฐ๋ ๊ฐ์ฌ.
- ์ฝ๊ธฐ ์ ์ฉ ์์ฑ ์์ฑ: ๊ฐ์ฒด ์์ฑ ํ ํน์ ์์ฑ์ ์์ ๋ฐฉ์ง.
- ์์ฑ ๊ฐ ์ ํจ์ฑ ๊ฒ์ฌ: ์์ฑ ๊ฐ์ด ํ ๋น๋๊ธฐ ์ ์ ํน์ ๊ธฐ์ค์ ์ถฉ์กฑํ๋์ง ํ์ธ. ์๋ฅผ ๋ค์ด, ์ด๋ฉ์ผ ์ฃผ์ ํ์ ๊ฒ์ฆ ๋๋ ์ซ์๊ฐ ํน์ ๋ฒ์ ๋ด์ ์๋์ง ํ์ธ.
- ํ๋ผ์ด๋น ๋ฉ์๋ ์๋ฎฌ๋ ์ด์ : ํ๋ก์ ํธ๋ค๋ฌ๋ ์ฃผ๋ก ์์ฑ์ ์ฌ์ฉ๋์ง๋ง, ํจ์ ํธ์ถ์ ๊ฐ๋ก์ฑ๊ณ ํธ์ถ ์ปจํ ์คํธ๋ฅผ ํ์ธํ์ฌ ํ๋ผ์ด๋น ๋ฉ์๋๋ฅผ ์๋ฎฌ๋ ์ด์ ํ๋๋ก ์กฐ์ ํ ์๋ ์์ต๋๋ค.
๋ชจ๋ฒ ์ฌ๋ก
- ํ๋ผ์ด๋น ํ๋๋ฅผ ๋ช
ํํ๊ฒ ์ ์: ์ผ๊ด๋ ๋ช
๋ช
๊ท์น์ด๋
WeakMap์ ์ฌ์ฉํ์ฌ ํ๋ผ์ด๋น ํ๋๋ฅผ ๋ช ํํ๊ฒ ์๋ณํฉ๋๋ค. - ์ ๊ทผ ์ ์ด ๊ท์น ๋ฌธ์ํ: ๋ค๋ฅธ ๊ฐ๋ฐ์๋ค์ด ๊ฐ์ฒด์ ์ํธ ์์ฉํ๋ ๋ฐฉ๋ฒ์ ์ดํดํ ์ ์๋๋ก ํ๋ก์ ํธ๋ค๋ฌ์ ์ํด ๊ตฌํ๋ ์ ๊ทผ ์ ์ด ๊ท์น์ ๋ฌธ์ํํฉ๋๋ค.
- ์ฒ ์ ํ ํ ์คํธ: ํ๋ก์ ํธ๋ค๋ฌ๊ฐ ํ๋ผ์ด๋ฒ์๋ฅผ ์ฌ๋ฐ๋ฅด๊ฒ ๊ฐ์ ํ๊ณ ์๊ธฐ์น ์์ ๋์์ ์ผ์ผํค์ง ์๋์ง ์ฒ ์ ํ ํ ์คํธํฉ๋๋ค. ๋จ์ ํ ์คํธ๋ฅผ ์ฌ์ฉํ์ฌ ํ๋ผ์ด๋น ํ๋์ ๋ํ ์ ๊ทผ์ด ์ ์ ํ ์ ํ๋๊ณ ๊ณต๊ฐ ๋ฉ์๋๊ฐ ์์๋๋ก ๋์ํ๋์ง ํ์ธํฉ๋๋ค.
- ์ฑ๋ฅ ์ํฅ ๊ณ ๋ ค: ํ๋ก์ ํธ๋ค๋ฌ๋ก ์ธํด ๋ฐ์ํ๋ ์ฑ๋ฅ ์ค๋ฒํค๋๋ฅผ ์ธ์งํ๊ณ ํ์ํ ๊ฒฝ์ฐ ํธ๋ค๋ฌ ์ฝ๋๋ฅผ ์ต์ ํํฉ๋๋ค. ์ฝ๋๋ฅผ ํ๋กํ์ผ๋งํ์ฌ ํ๋ก์๋ก ์ธํ ์ฑ๋ฅ ๋ณ๋ชฉ ํ์์ ์๋ณํฉ๋๋ค.
- ์ฃผ์ํ์ฌ ์ฌ์ฉ: ํ๋ก์ ํธ๋ค๋ฌ๋ ๊ฐ๋ ฅํ ๋๊ตฌ์ด์ง๋ง ์ฃผ์ํด์ ์ฌ์ฉํด์ผ ํฉ๋๋ค. ๋์์ ๊ณ ๋ คํ๊ณ ์ ํ๋ฆฌ์ผ์ด์ ์ ์๊ตฌ์ ๊ฐ์ฅ ์ ํฉํ ์ ๊ทผ ๋ฐฉ์์ ์ ํํฉ๋๋ค.
- ๊ธ๋ก๋ฒ ๊ณ ๋ ค์ฌํญ: ์ฝ๋๋ฅผ ์ค๊ณํ ๋ ๋ฐ์ดํฐ ํ๋ผ์ด๋ฒ์๋ฅผ ๋๋ฌ์ผ ๋ฌธํ์ ๊ท๋ฒ๊ณผ ๋ฒ์ ์๊ตฌ์ฌํญ์ด ๊ตญ์ ์ ์ผ๋ก ๋ค์ํ๋ค๋ ์ ์ ๊ธฐ์ตํ์ธ์. ๊ตฌํ์ด ๋ค๋ฅธ ์ง์ญ์์ ์ด๋ป๊ฒ ์ธ์๋๊ฑฐ๋ ๊ท์ ๋ ์ ์๋์ง ๊ณ ๋ คํ์ธ์. ์๋ฅผ ๋ค์ด, ์ ๋ฝ์ GDPR(์ผ๋ฐ ๋ฐ์ดํฐ ๋ณดํธ ๊ท์ )์ ๊ฐ์ธ ๋ฐ์ดํฐ ์ฒ๋ฆฌ์ ์๊ฒฉํ ๊ท์น์ ๋ถ๊ณผํฉ๋๋ค.
๊ตญ์ ์ ์์
์ ์ธ๊ณ์ ์ผ๋ก ๋ถ์ฐ๋ ๊ธ์ต ์ ํ๋ฆฌ์ผ์ด์ ์ ์์ํด ๋ณด์ธ์. ์ ๋ฝ ์ฐํฉ์์๋ GDPR์ด ๊ฐ๋ ฅํ ๋ฐ์ดํฐ ๋ณดํธ ์กฐ์น๋ฅผ ์๋ฌดํํฉ๋๋ค. ํ๋ก์ ํธ๋ค๋ฌ๋ฅผ ์ฌ์ฉํ์ฌ ๊ณ ๊ฐ ๊ธ์ต ๋ฐ์ดํฐ์ ๋ํ ์๊ฒฉํ ์ ๊ทผ ์ ์ด๋ฅผ ๊ฐ์ ํ๋ฉด ๊ท์ ์ ์ค์ํ ์ ์์ต๋๋ค. ๋ง์ฐฌ๊ฐ์ง๋ก, ๊ฐ๋ ฅํ ์๋น์ ๋ณดํธ๋ฒ์ด ์๋ ๊ตญ๊ฐ์์๋ ํ๋ก์ ํธ๋ค๋ฌ๋ฅผ ์ฌ์ฉํ์ฌ ์ฌ์ฉ์ ๊ณ์ ์ค์ ์ ๋ฌด๋จ ์์ ์ ๋ฐฉ์งํ ์ ์์ต๋๋ค.
์ฌ๋ฌ ๊ตญ๊ฐ์์ ์ฌ์ฉ๋๋ ์๋ฃ ์ ํ๋ฆฌ์ผ์ด์ ์์๋ ํ์ ๋ฐ์ดํฐ ํ๋ผ์ด๋ฒ์๊ฐ ๊ฐ์ฅ ์ค์ํฉ๋๋ค. ํ๋ก์ ํธ๋ค๋ฌ๋ ํ์ง ๊ท์ ์ ๋ฐ๋ผ ๋ค๋ฅธ ์์ค์ ์ ๊ทผ์ ๊ฐ์ ํ ์ ์์ต๋๋ค. ์๋ฅผ ๋ค์ด, ์ผ๋ณธ์ ์์ฌ๋ ๋ฏธ๊ตญ์ ๊ฐํธ์ฌ์ ๋ค๋ฅธ ๋ฐ์ดํฐ ๊ฐ์ธ ์ ๋ณด ๋ณดํธ๋ฒ์ผ๋ก ์ธํด ๋ค๋ฅธ ๋ฐ์ดํฐ ์ธํธ์ ์ ๊ทผํ ์ ์์ต๋๋ค.
๊ฒฐ๋ก
JavaScript ํ๋ก์ ํธ๋ค๋ฌ๋ ์บก์ํ๋ฅผ ๊ฐ์ ํ๊ณ ํ๋ผ์ด๋น ํ๋๋ฅผ ์๋ฎฌ๋ ์ด์
ํ๊ธฐ ์ํ ๊ฐ๋ ฅํ๊ณ ์ ์ฐํ ๋ฉ์ปค๋์ฆ์ ์ ๊ณตํฉ๋๋ค. ์ฑ๋ฅ ์ค๋ฒํค๋๊ฐ ์๊ณ ๋ค๋ฅธ ์ ๊ทผ ๋ฐฉ์๋ณด๋ค ๊ตฌํ์ด ๋ ๋ณต์กํ ์ ์์ง๋ง, ์์ฑ ์ ๊ทผ์ ๋ํ ์ธ๋ฐํ ์ ์ด๋ฅผ ์ ๊ณตํ๋ฉฐ ์ค๋๋ JavaScript ํ๊ฒฝ์์๋ ์ฌ์ฉํ ์ ์์ต๋๋ค. ์ด์ , ๋จ์ ๋ฐ ๋ชจ๋ฒ ์ฌ๋ก๋ฅผ ์ดํดํจ์ผ๋ก์จ JavaScript ์ฝ๋์ ๋ณด์, ์ ์ง๋ณด์์ฑ ๋ฐ ๊ฒฌ๊ณ ์ฑ์ ํฅ์์ํค๊ธฐ ์ํด ํ๋ก์ ํธ๋ค๋ฌ๋ฅผ ํจ๊ณผ์ ์ผ๋ก ํ์ฉํ ์ ์์ต๋๋ค. ๊ทธ๋ฌ๋ ํ๋ JavaScript ํ๋ก์ ํธ๋ ์ผ๋ฐ์ ์ผ๋ก ๋ ์ฐ์ํ ์ฑ๋ฅ๊ณผ ๊ฐ๋จํ ๊ตฌ๋ฌธ ๋๋ฌธ์ ํ๋ผ์ด๋น ํ๋์ ๋ํด # ๊ตฌ๋ฌธ์ ์ฌ์ฉํ๋ ๊ฒ์ ์ ํธํด์ผ ํ๋ฉฐ, ์ด๋ ์ค๋๋ ํ๊ฒฝ๊ณผ์ ํธํ์ฑ์ด ์๊ฒฉํ ์๊ตฌ ์ฌํญ์ด ์๋ ํ ๊ทธ๋ ์ต๋๋ค. ์ ํ๋ฆฌ์ผ์ด์
์ ๊ตญ์ ํํ๊ณ ์ฌ๋ฌ ๊ตญ๊ฐ์ ๋ฐ์ดํฐ ๊ฐ์ธ ์ ๋ณด ๋ณดํธ ๊ท์ ์ ๊ณ ๋ คํ ๋ ํ๋ก์ ํธ๋ค๋ฌ๋ ์ง์ญ๋ณ ์ ๊ทผ ์ ์ด ๊ท์น์ ๊ฐ์ ํ๋ ๋ฐ ์ ์ฉํ ์ ์์ผ๋ฉฐ, ๊ถ๊ทน์ ์ผ๋ก ๋ ์์ ํ๊ณ ๊ท์ ์ ์ค์ํ๋ ๊ธ๋ก๋ฒ ์ ํ๋ฆฌ์ผ์ด์
์ ๊ธฐ์ฌํ ์ ์์ต๋๋ค.