JavaScript ๋น๊ณต๊ฐ ํ๋, ์บก์ํ ์์น, ๊ทธ๋ฆฌ๊ณ ๊ฒฌ๊ณ ํ๊ณ ์ ์ง๋ณด์ ๊ฐ๋ฅํ ์ฝ๋๋ฅผ ์ํ ๋ฐ์ดํฐ ํ๋ผ์ด๋ฒ์ ๊ฐ์ ๋ฐฉ๋ฒ์ ๋ํ ์ฌ์ธต ๋ถ์.
JavaScript ๋น๊ณต๊ฐ ํ๋ ์ ๊ทผ ์ ์ด: ์บก์ํ ๊ฐ์
์บก์ํ๋ ๋ฐ์ดํฐ ์จ๊ธฐ๊ธฐ์ ์ ์ด๋ ์ ๊ทผ์ ์ด์งํ๋ ๊ฐ์ฒด ์งํฅ ํ๋ก๊ทธ๋๋ฐ(OOP)์ ๊ธฐ๋ณธ ์์น์ ๋๋ค. JavaScript์์๋ ์ง์ ํ ์บก์ํ๋ฅผ ๋ฌ์ฑํ๋ ๊ฒ์ด ์ญ์ฌ์ ์ผ๋ก ์ด๋ ค์ ์ต๋๋ค. ๊ทธ๋ฌ๋ ๋น๊ณต๊ฐ ํด๋์ค ํ๋(private class fields)๊ฐ ๋์ ๋๋ฉด์, ์ด์ JavaScript๋ ๋ฐ์ดํฐ ํ๋ผ์ด๋ฒ์๋ฅผ ๊ฐ์ ํ ์ ์๋ ๊ฐ๋ ฅํ ๋ฉ์ปค๋์ฆ์ ์ ๊ณตํฉ๋๋ค. ์ด ๊ธ์์๋ JavaScript ๋น๊ณต๊ฐ ํ๋, ๊ทธ ์ด์ , ์๋ ๋ฐฉ์์ ๋ํด ํ๊ตฌํ๊ณ , ์ฌ์ฉ๋ฒ์ ์ค๋ช ํ๊ธฐ ์ํ ์ค์ ์์ ๋ฅผ ์ ๊ณตํฉ๋๋ค.
์บก์ํ๋ ๋ฌด์์ธ๊ฐ?
์บก์ํ๋ ๋ฐ์ดํฐ(์์ฑ ๋๋ ํ๋กํผํฐ)์ ํด๋น ๋ฐ์ดํฐ์ ๋ํด ์๋ํ๋ ๋ฉ์๋(ํจ์)๋ฅผ ๋จ์ผ ๋จ์, ์ฆ ๊ฐ์ฒด ๋ด์ ๋ฌถ๋ ๊ฒ์ ๋๋ค. ์ด๋ ๊ฐ์ฒด์ ์ผ๋ถ ๊ตฌ์ฑ ์์์ ๋ํ ์ง์ ์ ์ธ ์ ๊ทผ์ ์ ํํ์ฌ ์๋ํ์ง ์์ ์์ ์ ๋ฐฉ์งํ๊ณ ๋ฐ์ดํฐ ๋ฌด๊ฒฐ์ฑ์ ๋ณด์ฅํฉ๋๋ค. ์บก์ํ๋ ๋ค์๊ณผ ๊ฐ์ ๋ช ๊ฐ์ง ์ฃผ์ ์ด์ ์ ์ ๊ณตํฉ๋๋ค:
- ๋ฐ์ดํฐ ์จ๊ธฐ๊ธฐ: ๋ด๋ถ ๋ฐ์ดํฐ์ ๋ํ ์ง์ ์ ์ธ ์ ๊ทผ์ ๋ฐฉ์งํ์ฌ ์ฐ๋ฐ์ ์ด๊ฑฐ๋ ์ ์์ ์ธ ์์ ์ผ๋ก๋ถํฐ ๋ณดํธํฉ๋๋ค.
- ๋ชจ๋์ฑ: ๋ ๋ฆฝ์ ์ธ ์ฝ๋ ๋จ์๋ฅผ ์์ฑํ์ฌ ์ฝ๋๋ฅผ ์ดํดํ๊ณ , ์ ์ง๋ณด์ํ๊ณ , ์ฌ์ฌ์ฉํ๊ธฐ ์ฝ๊ฒ ๋ง๋ญ๋๋ค.
- ์ถ์ํ: ๋ณต์กํ ๊ตฌํ ์ธ๋ถ ์ฌํญ์ ์ธ๋ถ ์ธ๊ณ๋ก๋ถํฐ ์จ๊ธฐ๊ณ , ๋จ์ํ๋ ์ธํฐํ์ด์ค๋ง ๋ ธ์ถํฉ๋๋ค.
- ์ฝ๋ ์ฌ์ฌ์ฉ์ฑ: ์บก์ํ๋ ๊ฐ์ฒด๋ ์ ํ๋ฆฌ์ผ์ด์ ์ ๋ค๋ฅธ ๋ถ๋ถ์ด๋ ๋ค๋ฅธ ํ๋ก์ ํธ์์ ์ฌ์ฌ์ฉ๋ ์ ์์ต๋๋ค.
- ์ ์ง๋ณด์์ฑ: ์บก์ํ๋ ๊ฐ์ฒด์ ๋ด๋ถ ๊ตฌํ ๋ณ๊ฒฝ์ ๊ณต๊ฐ ์ธํฐํ์ด์ค๊ฐ ๋์ผํ๊ฒ ์ ์ง๋๋ ํ, ์ด๋ฅผ ์ฌ์ฉํ๋ ์ฝ๋์ ์ํฅ์ ๋ฏธ์น์ง ์์ต๋๋ค.
JavaScript์์์ ์บก์ํ์ ์งํ
์ด๊ธฐ ๋ฒ์ ์ JavaScript์๋ ์ง์ ์ผ๋ก ๋น๊ณต๊ฐ์ธ ํ๋๋ฅผ ์ํ ๋ด์ฅ ๋ฉ์ปค๋์ฆ์ด ์์์ต๋๋ค. ๊ฐ๋ฐ์๋ค์ ํ๋ผ์ด๋ฒ์๋ฅผ ํ๋ด ๋ด๊ธฐ ์ํด ๋ค์ํ ๊ธฐ์ ์ ์์กดํ์ผ๋ฉฐ, ๊ฐ๊ฐ์ ๊ธฐ์ ์๋ ํ๊ณ๊ฐ ์์์ต๋๋ค:
1. ์ด๋ฆ ๊ท์น (๋ฐ์ค ์ ๋์ฌ)
์ผ๋ฐ์ ์ธ ๊ดํ์ ํ๋ ์ด๋ฆ ์์ ๋ฐ์ค(_
)์ ๋ถ์ฌ ๋น๊ณต๊ฐ๋ก ์ทจ๊ธํด์ผ ํจ์ ๋ํ๋ด๋ ๊ฒ์ด์์ต๋๋ค. ๊ทธ๋ฌ๋ ์ด๊ฒ์ ์์ ํ ๊ด๋ก์์ ๋ฟ์ด๋ฉฐ, ์ธ๋ถ ์ฝ๋๊ฐ ์ด๋ฌํ "๋น๊ณต๊ฐ" ํ๋์ ์ ๊ทผํ๊ณ ์์ ํ๋ ๊ฒ์ ๋ง์ ๋ฐฉ๋ฒ์ ์์์ต๋๋ค.
class Counter {
constructor() {
this._count = 0; // Convention: treat as private
}
increment() {
this._count++;
}
getCount() {
return this._count;
}
}
const counter = new Counter();
counter._count = 100; // Still accessible!
console.log(counter.getCount()); // Output: 100
ํ๊ณ: ํ๋ผ์ด๋ฒ์๊ฐ ์ค์ ๋ก ๊ฐ์ ๋์ง ์์์ต๋๋ค. ๊ฐ๋ฐ์๋ค์ ์๋ํ์ง ์์ ์ ๊ทผ์ ๋ง๊ธฐ ์ํด ๊ท์จ๊ณผ ์ฝ๋ ๋ฆฌ๋ทฐ์ ์์กดํด์ผ ํ์ต๋๋ค.
2. ํด๋ก์ (Closures)
ํด๋ก์ ๋ฅผ ์ฌ์ฉํ์ฌ ํจ์ ์ค์ฝํ ๋ด์ ๋น๊ณต๊ฐ ๋ณ์๋ฅผ ์์ฑํ ์ ์์์ต๋๋ค. ์ด๋ ๋ณ์๊ฐ ํจ์ ์ธ๋ถ์์ ์ง์ ์ ๊ทผํ ์ ์์๊ธฐ ๋๋ฌธ์ ๋ ๊ฐ๋ ฅํ ์์ค์ ํ๋ผ์ด๋ฒ์๋ฅผ ์ ๊ณตํ์ต๋๋ค.
function createCounter() {
let count = 0; // Private variable
return {
increment: function() {
count++;
},
getCount: function() {
return count;
}
};
}
const counter = createCounter();
counter.increment();
console.log(counter.getCount()); // Output: 1
// console.log(counter.count); // Error: counter.count is undefined
ํ๊ณ: ๊ฐ์ฒด์ ๊ฐ ์ธ์คํด์ค๋ ๋น๊ณต๊ฐ ๋ณ์์ ๋ณต์ฌ๋ณธ์ ๊ฐ๊ฐ ๊ฐ์ง๊ณ ์์ด ๋ฉ๋ชจ๋ฆฌ ์๋น๊ฐ ์ฆ๊ฐํ์ต๋๋ค. ๋ํ, ๊ฐ์ฒด์ ๋ค๋ฅธ ๋ฉ์๋ ๋ด์์ "๋น๊ณต๊ฐ" ๋ฐ์ดํฐ์ ์ ๊ทผํ๋ ค๋ฉด ์ ๊ทผ์ ํจ์๋ฅผ ๋ง๋ค์ด์ผ ํ๋๋ฐ, ์ด๋ ๋ฒ๊ฑฐ๋ก์ธ ์ ์์์ต๋๋ค.
3. WeakMap
WeakMap์ ๊ฐ์ฒด ์ธ์คํด์ค๋ฅผ ํค๋ก ์ฌ์ฉํ์ฌ ๋น๊ณต๊ฐ ๋ฐ์ดํฐ๋ฅผ ์ฐ๊ฒฐํ ์ ์๊ฒ ํจ์ผ๋ก์จ ๋ ์ ๊ตํ ์ ๊ทผ ๋ฐฉ์์ ์ ๊ณตํ์ต๋๋ค. WeakMap์ ๊ฐ์ฒด ์ธ์คํด์ค๊ฐ ๋ ์ด์ ์ฌ์ฉ๋์ง ์์ ๋ ๋ฐ์ดํฐ๊ฐ ๊ฐ๋น์ง ์ปฌ๋ ์ ๋๋๋ก ๋ณด์ฅํ์ต๋๋ค.
const _count = new WeakMap();
class Counter {
constructor() {
_count.set(this, 0);
}
increment() {
const currentCount = _count.get(this);
_count.set(this, currentCount + 1);
}
getCount() {
return _count.get(this);
}
}
const counter = new Counter();
counter.increment();
console.log(counter.getCount()); // Output: 1
// console.log(_count.get(counter)); // Error: _count is not accessible outside the module
ํ๊ณ: WeakMap์ ๊ด๋ฆฌํ๊ธฐ ์ํด ์ถ๊ฐ์ ์ธ ์์ฉ๊ตฌ ์ฝ๋๊ฐ ํ์ํ์ต๋๋ค. ๋น๊ณต๊ฐ ๋ฐ์ดํฐ์ ์ ๊ทผํ๋ ๊ฒ์ ์ง์ ์ ์ธ ํ๋ ์ ๊ทผ๋ณด๋ค ๋ ์ฅํฉํ๊ณ ๋ ์ง๊ด์ ์ด์์ต๋๋ค. ๋ํ, "ํ๋ผ์ด๋ฒ์"๋ ํด๋์ค ์์ค์ด ์๋ ๋ชจ๋ ์์ค์ด์์ต๋๋ค. WeakMap์ด ๋ ธ์ถ๋๋ฉด ์กฐ์๋ ์ ์์์ต๋๋ค.
JavaScript ๋น๊ณต๊ฐ ํ๋: ํ๋์ ์ธ ํด๊ฒฐ์ฑ
ES2015(ES6)์ ํจ๊ป ๋์
๋๊ณ ES2022์์ ํ์คํ๋ JavaScript์ ๋น๊ณต๊ฐ ํด๋์ค ํ๋๋ ์บก์ํ๋ฅผ ๊ฐ์ ํ๊ธฐ ์ํ ๋ด์ฅ๋๊ณ ๊ฐ๋ ฅํ ๋ฉ์ปค๋์ฆ์ ์ ๊ณตํฉ๋๋ค. ๋น๊ณต๊ฐ ํ๋๋ ํ๋ ์ด๋ฆ ์์ #
์ ๋์ฌ๋ฅผ ์ฌ์ฉํ์ฌ ์ ์ธ๋ฉ๋๋ค. ์ด๋ค์ ์ ์ธ๋ ํด๋์ค ๋ด๋ถ์์๋ง ์ ๊ทผํ ์ ์์ต๋๋ค. ์ด๋ JavaScript ์์ง์ด ํ๋ผ์ด๋ฒ์ ์ ์ฝ์ ๊ฐ์ ํ๋ฏ๋ก ์ง์ ํ ์บก์ํ๋ฅผ ์ ๊ณตํฉ๋๋ค.
๊ตฌ๋ฌธ
class MyClass {
#privateField;
constructor(initialValue) {
this.#privateField = initialValue;
}
getPrivateFieldValue() {
return this.#privateField;
}
}
์์
class Counter {
#count = 0; // Private field
increment() {
this.#count++;
}
getCount() {
return this.#count;
}
}
const counter = new Counter();
counter.increment();
console.log(counter.getCount()); // Output: 1
// console.log(counter.#count); // SyntaxError: Private field '#count' must be declared in an enclosing class
๋น๊ณต๊ฐ ํ๋์ ์ฃผ์ ํน์ง
- ์ ์ธ: ๋น๊ณต๊ฐ ํ๋๋ ์์ฑ์๋ ๋ค๋ฅธ ๋ฉ์๋๋ณด๋ค ๋จผ์ ํด๋์ค ๋ณธ๋ฌธ ๋ด๋ถ์ ์ ์ธ๋์ด์ผ ํฉ๋๋ค.
- ์ค์ฝํ: ๋น๊ณต๊ฐ ํ๋๋ ์ ์ธ๋ ํด๋์ค ๋ด๋ถ์์๋ง ์ ๊ทผํ ์ ์์ต๋๋ค. ์๋ธํด๋์ค์กฐ์ฐจ๋ ์ง์ ์ ๊ทผํ ์ ์์ต๋๋ค.
- SyntaxError: ์ ์ธ๋ ํด๋์ค ์ธ๋ถ์์ ๋น๊ณต๊ฐ ํ๋์ ์ ๊ทผํ๋ ค๊ณ ํ๋ฉด
SyntaxError
๊ฐ ๋ฐ์ํฉ๋๋ค. - ๊ณ ์ ์ฑ: ๊ฐ ํด๋์ค๋ ์์ ๋ง์ ๋น๊ณต๊ฐ ํ๋ ์งํฉ์ ๊ฐ์ง๋๋ค. ๋ ๊ฐ์ ๋ค๋ฅธ ํด๋์ค๊ฐ ๋์ผํ ์ด๋ฆ์ ๋น๊ณต๊ฐ ํ๋(์: ๋ ๋ค
#count
๋ฅผ ๊ฐ์ง)๋ฅผ ๊ฐ์ง ์ ์์ผ๋ฉฐ, ์ด๋ค์ ์๋ก ๊ตฌ๋ณ๋ฉ๋๋ค. - ์ญ์ ๋ถ๊ฐ: ๋น๊ณต๊ฐ ํ๋๋
delete
์ฐ์ฐ์๋ฅผ ์ฌ์ฉํ์ฌ ์ญ์ ํ ์ ์์ต๋๋ค.
๋น๊ณต๊ฐ ํ๋ ์ฌ์ฉ์ ์ด์
๋น๊ณต๊ฐ ํ๋๋ฅผ ์ฌ์ฉํ๋ฉด JavaScript ๊ฐ๋ฐ์ ์๋นํ ์ด์ ์ ์ ๊ณตํฉ๋๋ค:
- ๋ ๊ฐ๋ ฅํ ์บก์ํ: ์ง์ ํ ๋ฐ์ดํฐ ์จ๊ธฐ๊ธฐ๋ฅผ ์ ๊ณตํ์ฌ ๋ด๋ถ ์ํ๋ฅผ ์๋ํ์ง ์์ ์์ ์ผ๋ก๋ถํฐ ๋ณดํธํฉ๋๋ค. ์ด๋ ๋ ๊ฒฌ๊ณ ํ๊ณ ์ ๋ขฐํ ์ ์๋ ์ฝ๋๋ก ์ด์ด์ง๋๋ค.
- ์ฝ๋ ์ ์ง๋ณด์์ฑ ํฅ์: ๋น๊ณต๊ฐ ํ๋๊ฐ ์ง์ ์ ์ธ ์ ๊ทผ์ผ๋ก๋ถํฐ ๋ณดํธ๋๋ฏ๋ก ํด๋์ค์ ๋ด๋ถ ๊ตฌํ ๋ณ๊ฒฝ์ด ์ธ๋ถ ์ฝ๋๋ฅผ ์์์ํฌ ๊ฐ๋ฅ์ฑ์ด ์ ์ด์ง๋๋ค.
- ๋ณต์ก์ฑ ๊ฐ์: ๋น๊ณต๊ฐ ํ๋๋ ํด๋์ค ์์ ์ ๋ฉ์๋์ ์ํด์๋ง ์์ ๋๋ค๋ ํ์ ์ ๊ฐ์ง ์ ์์ผ๋ฏ๋ก ์ฝ๋์ ๋ํ ์ถ๋ก ์ ๋จ์ํํฉ๋๋ค.
- ๋ณด์ ๊ฐํ: ์ ์์ ์ธ ์ฝ๋๊ฐ ๊ฐ์ฒด ๋ด์ ๋ฏผ๊ฐํ ๋ฐ์ดํฐ์ ์ง์ ์ ๊ทผํ๊ณ ์กฐ์ํ๋ ๊ฒ์ ๋ฐฉ์งํฉ๋๋ค.
- ๋ ๋ช ํํ API ์ค๊ณ: ๊ฐ๋ฐ์๊ฐ ํด๋์ค์ ๋ํ ๋ช ํํ๊ณ ์ ์ ์๋ ๊ณต๊ฐ ์ธํฐํ์ด์ค๋ฅผ ์ ์ํ๋๋ก ์ฅ๋ คํ์ฌ ๋ ๋์ ์ฝ๋ ๊ตฌ์ฑ ๋ฐ ์ฌ์ฌ์ฉ์ฑ์ ์ด์งํฉ๋๋ค.
์ค์ฉ์ ์ธ ์์
๋ค์์ ๋ค์ํ ์๋๋ฆฌ์ค์์ ๋น๊ณต๊ฐ ํ๋๋ฅผ ์ฌ์ฉํ๋ ๋ช ๊ฐ์ง ์ค์ฉ์ ์ธ ์์ ์ ๋๋ค:
1. ์์ ํ ๋ฐ์ดํฐ ์ ์ฅ
API ํค๋ ๋น๋ฐ๋ฒํธ์ ๊ฐ์ ๋ฏผ๊ฐํ ์ฌ์ฉ์ ๋ฐ์ดํฐ๋ฅผ ์ ์ฅํ๋ ํด๋์ค๋ฅผ ์๊ฐํด ๋ณด์ธ์. ๋น๊ณต๊ฐ ํ๋๋ฅผ ์ฌ์ฉํ๋ฉด ์ด ๋ฐ์ดํฐ์ ๋ํ ๋ฌด๋จ ์ ๊ทผ์ ๋ฐฉ์งํ ์ ์์ต๋๋ค.
class User {
#apiKey;
constructor(apiKey) {
this.#apiKey = apiKey;
}
isValidAPIKey() {
// Perform validation logic here
return this.#validateApiKey(this.#apiKey);
}
#validateApiKey(apiKey) {
// Private method to validate the API Key
return apiKey.length > 10;
}
}
const user = new User("mysecretapikey123");
console.log(user.isValidAPIKey()); //Output: True
//console.log(user.#apiKey); //SyntaxError: Private field '#apiKey' must be declared in an enclosing class
2. ๊ฐ์ฒด ์ํ ์ ์ด
๋น๊ณต๊ฐ ํ๋๋ ๊ฐ์ฒด ์ํ์ ๋ํ ์ ์ฝ ์กฐ๊ฑด์ ๊ฐ์ ํ๋ ๋ฐ ์ฌ์ฉ๋ ์ ์์ต๋๋ค. ์๋ฅผ ๋ค์ด, ๊ฐ์ด ํน์ ๋ฒ์ ๋ด์ ์๋๋ก ๋ณด์ฅํ ์ ์์ต๋๋ค.
class TemperatureSensor {
#temperature;
constructor(initialTemperature) {
this.setTemperature(initialTemperature);
}
getTemperature() {
return this.#temperature;
}
setTemperature(temperature) {
if (temperature < -273.15) { // Absolute zero
throw new Error("Temperature cannot be below absolute zero.");
}
this.#temperature = temperature;
}
}
try {
const sensor = new TemperatureSensor(25);
console.log(sensor.getTemperature()); // Output: 25
sensor.setTemperature(-300); // Throws an error
} catch (error) {
console.error(error.message);
}
3. ๋ณต์กํ ๋ก์ง ๊ตฌํ
๋น๊ณต๊ฐ ํ๋๋ ํด๋์ค์ ๊ตฌํ์๋ง ๊ด๋ จ๋ ์ค๊ฐ ๊ฒฐ๊ณผ๋ ๋ด๋ถ ์ํ๋ฅผ ์ ์ฅํ๋ ๋ฐ ์ฌ์ฉ๋ ์ ์์ต๋๋ค.
class Calculator {
#internalResult = 0;
add(number) {
this.#internalResult += number;
return this;
}
subtract(number) {
this.#internalResult -= number;
return this;
}
getResult() {
return this.#internalResult;
}
}
const calculator = new Calculator();
const result = calculator.add(10).subtract(5).getResult();
console.log(result); // Output: 5
// console.log(calculator.#internalResult); // SyntaxError
๋น๊ณต๊ฐ ํ๋ vs. ๋น๊ณต๊ฐ ๋ฉ์๋
๋น๊ณต๊ฐ ํ๋ ์ธ์๋ JavaScript๋ ๋์ผํ #
์ ๋์ฌ๋ฅผ ์ฌ์ฉํ์ฌ ์ ์ธ๋๋ ๋น๊ณต๊ฐ ๋ฉ์๋๋ ์ง์ํฉ๋๋ค. ๋น๊ณต๊ฐ ๋ฉ์๋๋ ์ด๋ฅผ ์ ์ํ ํด๋์ค ๋ด์์๋ง ํธ์ถํ ์ ์์ต๋๋ค.
์์
class MyClass {
#privateMethod() {
console.log("This is a private method.");
}
publicMethod() {
this.#privateMethod(); // Call the private method
}
}
const myObject = new MyClass();
myObject.publicMethod(); // Output: This is a private method.
// myObject.#privateMethod(); // SyntaxError: Private field '#privateMethod' must be declared in an enclosing class
๋น๊ณต๊ฐ ๋ฉ์๋๋ ๋ด๋ถ ๋ก์ง์ ์บก์ํํ๊ณ ์ธ๋ถ ์ฝ๋๊ฐ ๊ฐ์ฒด์ ๋์์ ์ง์ ์ํฅ์ ๋ฏธ์น๋ ๊ฒ์ ๋ฐฉ์งํ๋ ๋ฐ ์ ์ฉํฉ๋๋ค. ์ด๋ค์ ์ข ์ข ๋ณต์กํ ์๊ณ ๋ฆฌ์ฆ์ด๋ ์ํ ๊ด๋ฆฌ๋ฅผ ๊ตฌํํ๊ธฐ ์ํด ๋น๊ณต๊ฐ ํ๋์ ํจ๊ป ์๋ํฉ๋๋ค.
์ฃผ์์ฌํญ ๋ฐ ๊ณ ๋ ค์ฌํญ
๋น๊ณต๊ฐ ํ๋๋ ์บก์ํ๋ฅผ ์ํ ๊ฐ๋ ฅํ ๋ฉ์ปค๋์ฆ์ ์ ๊ณตํ์ง๋ง, ๊ณ ๋ คํด์ผ ํ ๋ช ๊ฐ์ง ์ฃผ์์ฌํญ์ด ์์ต๋๋ค:
- ํธํ์ฑ: ๋น๊ณต๊ฐ ํ๋๋ ๋น๊ต์ ์๋ก์ด JavaScript ๊ธฐ๋ฅ์ด๋ฏ๋ก ์ด์ ๋ฒ์ ์ ๋ธ๋ผ์ฐ์ ๋ JavaScript ํ๊ฒฝ์์๋ ์ง์๋์ง ์์ ์ ์์ต๋๋ค. ํธํ์ฑ์ ๋ณด์ฅํ๋ ค๋ฉด Babel๊ณผ ๊ฐ์ ํธ๋์คํ์ผ๋ฌ๋ฅผ ์ฌ์ฉํ์ธ์.
- ์์ ๋ถ๊ฐ: ๋น๊ณต๊ฐ ํ๋๋ ์๋ธํด๋์ค์์ ์ ๊ทผํ ์ ์์ต๋๋ค. ๋ถ๋ชจ ํด๋์ค์ ์๋ธํด๋์ค ๊ฐ์ ๋ฐ์ดํฐ๋ฅผ ๊ณต์ ํด์ผ ํ๋ ๊ฒฝ์ฐ, protected ํ๋(JavaScript์์ ๊ธฐ๋ณธ์ ์ผ๋ก ์ง์๋์ง๋ ์์ง๋ง ์ ์คํ ์ค๊ณ๋ TypeScript๋ก ์๋ฎฌ๋ ์ด์ ํ ์ ์์) ์ฌ์ฉ์ ๊ณ ๋ คํ์ธ์.
- ๋๋ฒ๊น : ๋๋ฒ๊ฑฐ์์ ๋น๊ณต๊ฐ ํ๋์ ๊ฐ์ ์ง์ ๊ฒ์ฌํ ์ ์์ผ๋ฏ๋ก ๋น๊ณต๊ฐ ํ๋๋ฅผ ์ฌ์ฉํ๋ ์ฝ๋๋ฅผ ๋๋ฒ๊น ํ๋ ๊ฒ์ด ์ฝ๊ฐ ๋ ์ด๋ ค์ธ ์ ์์ต๋๋ค.
- ์ค๋ฒ๋ผ์ด๋ฉ: ๋น๊ณต๊ฐ ๋ฉ์๋๋ ๋ถ๋ชจ ํด๋์ค์ ๋ฉ์๋๋ฅผ ๊ฐ๋ฆด ์(shadow) ์์ง๋ง, ๋น๊ณต๊ฐ ๋ฉ์๋์๋ ๋คํ์ฑ์ด ์๊ธฐ ๋๋ฌธ์ ๊ณ ์ ์ ์ธ ๊ฐ์ฒด ์งํฅ์ ์๋ฏธ์์ ์ง์ ์ผ๋ก ์ค๋ฒ๋ผ์ด๋ํ์ง๋ ์์ต๋๋ค.
๋น๊ณต๊ฐ ํ๋์ ๋์ (์ค๋๋ ํ๊ฒฝ์ฉ)
๋น๊ณต๊ฐ ํ๋๋ฅผ ์ง์ํ์ง ์๋ ์ค๋๋ JavaScript ํ๊ฒฝ์ ์ง์ํด์ผ ํ๋ ๊ฒฝ์ฐ, ์์ ์ธ๊ธํ ์ด๋ฆ ๊ท์น, ํด๋ก์ ๋๋ WeakMap๊ณผ ๊ฐ์ ๊ธฐ์ ์ ์ฌ์ฉํ ์ ์์ต๋๋ค. ๊ทธ๋ฌ๋ ์ด๋ฌํ ์ ๊ทผ ๋ฐฉ์์ ํ๊ณ๋ฅผ ์ธ์งํด์ผ ํฉ๋๋ค.
๊ฒฐ๋ก
JavaScript ๋น๊ณต๊ฐ ํ๋๋ ์บก์ํ๋ฅผ ๊ฐ์ ํ๊ณ , ์ฝ๋ ์ ์ง๋ณด์์ฑ์ ํฅ์์ํค๋ฉฐ, ๋ณต์ก์ฑ์ ์ค์ด๊ณ , ๋ณด์์ ๊ฐํํ๊ธฐ ์ํ ๊ฐ๋ ฅํ๊ณ ํ์คํ๋ ๋ฉ์ปค๋์ฆ์ ์ ๊ณตํฉ๋๋ค. ๋น๊ณต๊ฐ ํ๋๋ฅผ ์ฌ์ฉํจ์ผ๋ก์จ ๋ ๊ฒฌ๊ณ ํ๊ณ ์ ๋ขฐํ ์ ์์ผ๋ฉฐ ์ ์ ๋ฆฌ๋ JavaScript ์ฝ๋๋ฅผ ๋ง๋ค ์ ์์ต๋๋ค. ๋น๊ณต๊ฐ ํ๋๋ฅผ ์ฑํํ๋ ๊ฒ์ ๋ ๊นจ๋ํ๊ณ ์ ์ง๋ณด์ ๊ฐ๋ฅํ๋ฉฐ ์์ ํ JavaScript ์ ํ๋ฆฌ์ผ์ด์ ์ ์์ฑํ๋ ๋ฐ ์ค์ํ ๋จ๊ณ์ ๋๋ค. JavaScript๊ฐ ๊ณ์ ๋ฐ์ ํจ์ ๋ฐ๋ผ ๋น๊ณต๊ฐ ํ๋๋ ์์ฌํ ์ฌ์ง ์์ด ์ธ์ด ์ํ๊ณ์์ ์ ์ ๋ ์ค์ํ ๋ถ๋ถ์ด ๋ ๊ฒ์ ๋๋ค.
๋ค์ํ ๋ฌธํ์ ๋ฐฐ๊ฒฝ์ ๊ฐ์ง ๊ฐ๋ฐ์๋ค์ด ๊ธ๋ก๋ฒ ํ๋ก์ ํธ์ ๊ธฐ์ฌํจ์ ๋ฐ๋ผ, ์ด๋ฌํ ์บก์ํ ์์น์ ์ดํดํ๊ณ ์ผ๊ด๋๊ฒ ์ ์ฉํ๋ ๊ฒ์ ํ์ ์ฑ๊ณต์ ๋งค์ฐ ์ค์ํฉ๋๋ค. ๋น๊ณต๊ฐ ํ๋๋ฅผ ์ฑํํจ์ผ๋ก์จ ์ ์ธ๊ณ ๊ฐ๋ฐํ์ ๋ฐ์ดํฐ ํ๋ผ์ด๋ฒ์๋ฅผ ๊ฐ์ ํ๊ณ , ์ฝ๋ ์ผ๊ด์ฑ์ ๊ฐ์ ํ๋ฉฐ, ๋ ์ ๋ขฐํ ์ ์๊ณ ํ์ฅ ๊ฐ๋ฅํ ์ ํ๋ฆฌ์ผ์ด์ ์ ๊ตฌ์ถํ ์ ์์ต๋๋ค.
๋ ์์๋ณด๊ธฐ
- MDN ์น ๋ฌธ์: Private class fields
- Babel: Babel JavaScript Compiler