[Javascript] Closure
24. ํด๋ก์ Closure
- ํด๋ก์
closure
๋ ๋ํดํ๊ธฐ๋ก ์ ๋ช ํ ์๋ฐ์คํฌ๋ฆฝํธ์ ๊ฐ๋ ์ค ํ๋๋ก, ์คํ ์ปจํ ์คํธ์ ๋ํ ์ฌ์ ์ง์์ด ์์ผ๋ฉด ์ดํดํ๊ธฐ ์ด๋ ค์ด ๊ฐ๋ ์ ์๋๋ค. - ํด๋ก์ ๋ ์๋ฐ์คํฌ๋ฆฝํธ ๊ณ ์ ์ ๊ฐ๋ ์ด ์๋๋ค. ํจ์๋ฅผ ์ผ๊ธ ๊ฐ์ฒด๋ก ์ทจ๊ธํ๋ ํจ์ํ ํ๋ก๊ทธ๋๋ฐ ์ธ์ด(์: ํ์ค์ผ, ๋ฆฌ์คํ, ์ผ๋ญ, ์ค์นผ๋ผ ๋ฑ)์์ ์ฌ์ฉ๋๋ ์ค์ํ ํน์ฑ์ด๋ค. ๊ณ ์ ์ ๊ฐ๋ ์ด ์๋๋ฏ๋ก ECMAScript ์ฌ์์ ๋ฑ์ฅํ์ง ์๋๋ค.
- MDN์์ โํด๋ก์ ๋ ํจ์์ ๊ทธ ํจ์๊ฐ ์ ์ธ๋ ๋ ์์ปฌ ํ๊ฒฝ๊ณผ์ ์กฐํฉ์ด๋ค.โ๋ผ๊ณ ์ ์ํ๊ณ ์๋ค.
24.1 ๋ ์์ปฌ ์ค์ฝํ
- ์๋ฐ์คํฌ๋ฆฝํธ ์์ง์ ํจ์๋ฅผ ์ด๋์ ํธ์ถํ๋์ง๊ฐ ์๋๋ผ ํจ์๋ฅผ ์ด๋์ ์ ์ํ๋์ง์ ๋ฐ๋ผ ์์ ์ค์ฝํ๋ฅผ ๊ฒฐ์ ํ๋ค. ์ด๋ฅผ ๋ ์์ปฌ ์ค์ฝํ(์ ์ ์ค์ฝํ)๋ผ ํ๋ค.
- ๋ ์์ปฌ ํ๊ฒฝ์ โ์ธ๋ถ ๋ ์์ปฌ ํ๊ฒฝ์ ๋ํ ์ฐธ์กฐโ์ ์ ์ฅํ ์ฐธ์กฐ๊ฐ, ์ฆ ์์ ์ค์ฝํ์ ๋ํ ์ฐธ์กฐ๋ ํจ์ ์ ์๊ฐ ํ๊ฐ๋๋ ์์ ์ ํจ์๊ฐ ์ ์๋ ํ๊ฒฝ(์์น)์ ์ํด ๊ฒฐ์ ๋๋ค. ์ด๊ฒ์ด ๋ฐ๋ก ๋ ์์ปฌ ์ค์ฝํ๋ค.
24.2 ํจ์ ๊ฐ์ฒด์ ๋ด๋ถ ์ฌ๋กฏ [[Environment]]
- ํจ์๋ ์์ ์ด ์ ์๋ ํ๊ฒฝ, ์ฆ ์์ ์ค์ฝํ๋ฅผ ๊ธฐ์ตํด์ผ ํ๋ค. ์ด๋ฅผ ์ํด ํจ์๋ ์์ ์ ๋ด๋ถ ์ฌ๋กฏ [[Environment]]์ ์์ ์ด ์ ์๋ ํ๊ฒฝ, ์ฆ ์์ ์ค์ฝํ์ ์ฐธ์กฐ๋ฅผ ์ ์ฅํ๋ค.
- ํจ์ ๊ฐ์ฒด์ ๋ด๋ถ ์ฌ๋กฏ [[Environment]]์ ์ ์ฅ๋ ํ์ฌ ์คํ ์ค์ธ ์คํ ์ปจํ
์คํธ์ ๋ ์์ปฌ ํ๊ฒฝ์ ์ฐธ์กฐ๊ฐ ๋ฐ๋ก ์์ ์ค์ฝํ์ด๋ค. ๋ํ ์์ ์ด ํธ์ถ๋์์ ๋ ์์ฑ๋ ํจ์ ๋ ์์ปฌ ํ๊ฒฝ์ โ์ธ๋ถ ๋ ์์ปฌ ํ๊ฒฝ์ ๋ํ ์ฐธ์กฐโ์ ์ ์ฅ๋ ์ฐธ์กฐ๊ฐ์ด๋ค. ํจ์ ๊ฐ์ฒด๋ ๋ด๋ถ ์ฌ๋กฏ [[Environment]]์ ์ ์ฅํ ๋ ์์ปฌ ํ๊ฒฝ์ ์ฐธ์กฐ, ์ฆ ์์ ์ค์ฝํ๋ฅผ ์์ ์ด ์กด์ฌํ๋ ํ ๊ธฐ์ตํ๋ค.
24.3 ํด๋ก์ ์ ๋ ์์ปฌ ํ๊ฒฝ
- ๋ค์ ์์ ๋ฅผ ์ดํด๋ณด์
const x = 1;
// <1>
function outer() {
const x = 10;
const y = 5;
const inner = function() { console.log(x); }; // <2>
return inner;
}
const innerFunc = outer(); // <3>
innerFunc(); // <4> 10
- outer ํจ์๋ฅผ ํธ์ถ<3>ํ๋ฉด outer ํจ์๋ ์ค์ฒฉ ํจ์ inner๋ฅผ ๋ฐํํ๊ณ ์๋ช
์ฃผ๊ธฐ
life cycle
๋ฅผ ๋ง๊ฐํ๋ค. ์ฆ, outer ํจ์์ ํธ์ถ์ด ์ข ๋ฃํ๋ฉด outer ํจ์์ ์คํ ์ปจํ ์คํธ๋ ์คํ ์ปจํ ์คํธ ์คํ์์ ์ ๊ฑฐpop
๋๋ค. ์ด๋ outer ํจ์์ ์ง์ญ ๋ณ์ x์ ๋ณ์ ๊ฐ 10์ ์ ์ฅํ๊ณ ์๋ outer ํจ์์ ์คํ ์ปจํ ์คํธ๊ฐ ์ ๊ฑฐ๋์์ผ๋ฏ๋ก outer ํจ์์ ์ง์ญ ๋ณ์ x ๋ํ ์๋ช ์ฃผ๊ธฐ๋ฅผ ๋ง๊ฐํ๋ค. ๋ฐ๋ผ์ outer ํจ์์ ์ง์ญ ๋ณ์ x๋ ๋๋ ์ ํจํ์ง ์๊ฒ ๋์ด x ๋ณ์์ ์ ๊ทผํ ์ ์๋ ๋ฐฉ๋ฒ์ ๋ฌ๋ฆฌ ์์ด ๋ณด์ธ๋ค. - ๊ทธ๋ฌ๋ ์ ์ฝ๋์ ์คํ ๊ฒฐ๊ณผ<4>๋ outer ํจ์์ ์ง์ญ ๋ณ์ x์ ๊ฐ์ธ 10์ด๋ค. ์ด๋ฏธ ์๋ช ์ฃผ๊ธฐ๊ฐ ์ข ๋ฃ๋์ด ์คํ ์ปจํ ์คํธ ์คํ์์ ์ ๊ฑฐ๋ outerํจ์์ ์ง์ญ ๋ณ์ x๊ฐ ๋ค์ ๋ถํํ ๋ฏ ๋์ํ๊ณ ์๋ค.
- ์ด์ฒ๋ผ ์ธ๋ถ ํจ์๋ณด๋ค ์ค์ฒฉ ํจ์๊ฐ ๋ ์ค๋ ์ ์ง๋๋ ๊ฒฝ์ฐ ์ค์ฒฉ ํจ์๋ ์ด๋ฏธ ์๋ช
์ฃผ๊ธฐ๊ฐ ์ข
๋ฃํ ์ธ๋ถ ํจ์์ ๋ณ์๋ฅผ ์ฐธ์กฐํ ์ ์๋ค. ์ด๋ฌํ ์ค์ฒฉ ํจ์๋ฅผ ํด๋ก์
closure
๋ผ๊ณ ๋ถ๋ฅธ๋ค. - ์๋ฐ์คํฌ๋ฆฝํธ์ ๋ชจ๋ ํจ์๋ ์์ ์ ์์ ์ค์ฝํ๋ฅผ ๊ธฐ์ตํ๋ค๊ณ ํ๋ค. ํจ์๋ฅผ ์ด๋์ ํธ์ถํ๋ ์๊ด์์ด ํจ์๋ ์ธ์ ๋ ์์ ์ด ๊ธฐ์ตํ๋ ์์ ์ค์ฝํ์ ์๋ณ์๋ฅผ ์ฐธ์กฐํ ์ ์์ผ๋ฉฐ ์๋ณ์์ ๋ฐ์ธ๋ฉ๋ ๊ฐ์ ๋ณ๊ฒฝํ ์๋ ์๋ค.
- ์ ์์ ์์ ์ค์ฒฉ ํจ์ inner๋ ์์ ์ค์ฝํ์ x, y ์๋ณ์ ์ค์ x๋ง ์ฐธ์กฐํ๊ณ ์๋ค. ์ด๋ฐ ๊ฒฝ์ฐ ๋๋ถ๋ถ์ ๋ชจ๋ ๋ธ๋ผ์ฐ์ ๋ ์ต์ ํ๋ฅผ ํตํด ์์ ์ค์ฝํ์ ์๋ณ์ ์ค์์ ํด๋ก์ ๊ฐ ์ฐธ์กฐํ๊ณ ์๋ ์๋ณ์๋ง์ ๊ธฐ์ตํ๋ค.
- ํด๋ก์ ์ ์ํด ์ฐธ์กฐ๋๋ ์์ ์ค์ฝํ์ ๋ณ์๋ฅผ ์์ ๋ณ์
free variable
๋ผ๊ณ ๋ถ๋ฅธ๋ค. ํด๋ก์ closure
๋ โํจ์๊ฐ ์์ ๋ณ์์ ๋ํด ๋ซํ์๋คclosed
โ๋ผ๋ ์๋ฏธ๋ค. ์ด๋ฅผ ์ข ๋ ์๊ธฐ ์ฝ๊ฒ ์์ญํ์๋ฉด โ์์ ๋ณ์์ ๋ฌถ์ฌ์๋ ํจ์โ๋ผ๊ณ ํ ์ ์๋ค.
24.4 ํด๋ก์ ์ ํ์ฉ
- ํด๋ก์ ๋ ์ํ
state
๋ฅผ ์์ ํ๊ฒ ๋ณ๊ฒฝํ๊ณ ์ ์งํ๊ธฐ ์ํด ์ฌ์ฉํ๋ค. ๋ค์ ๋งํด, ์ํ๊ฐ ์๋์น ์๊ฒ ๋ณ๊ฒฝ๋์ง ์๋๋ก ์ํ๋ฅผ ์์ ํ๊ฒ ์๋information hiding
ํ๊ณ ํน์ ํจ์์๊ฒ๋ง ์ํ ๋ณ๊ฒฝ์ ํ์ฉํ๊ธฐ ์ํด ์ฌ์ฉํ๋ค.
// ์นด์ดํธ ์ํ ๋ณ๊ฒฝ ํจ์
const increase = (function() {
// ์นด์ดํธ ์ํ ๋ณ์
let num = 0;
// ํด๋ก์
return function() {
// ์นด์ดํธ ์ํ๋ฅผ 1๋งํผ ์ฆ๊ฐ์ํจ๋ค.
return ++num;
}
})());
console.log(increase()); // 1
console.log(increase()); // 2
console.log(increase()); // 3
- ์ ์ฝ๋๊ฐ ์คํ๋๋ฉด ์ฆ์ ์คํ ํจ์๊ฐ ํธ์ถ๋๊ณ ์ฆ์ ์คํ ํจ์๊ฐ ๋ฐํํ ํจ์๊ฐ increase ๋ณ์์ ํ ๋น๋๋ค. increase ๋ณ์์ ํ ๋น๋ ํจ์๋ ์์ ์ด ์ ์๋ ์์น์ ์ํด ๊ฒฐ์ ๋ ์์ ์ค์ฝํ์ธ ์ฆ์ ์คํ ํจ์์ ๋ ์์ปฌ ํ๊ฒฝ์ ๊ธฐ์ตํ๋ ํด๋ก์ ๋ค.
- ์ฆ์ ์คํ ํจ์๋ ํ ๋ฒ๋ง ์คํ๋๋ฏ๋ก increase๊ฐ ํธ์ถ๋ ๋๋ง๋ค num ๋ณ์๊ฐ ์ฌ์ฐจ ์ด๊ธฐํ๋ ์ผ์ ์์ ๊ฒ์ด๋ค. ๋ํ num ๋ณ์๋ ์ธ๋ถ์์ ์ง์ ์ ๊ทผํ ์ ์๋ ์๋๋ private ๋ณ์์ด๋ฏ๋ก ์ ์ญ ๋ณ์๋ฅผ ์ฌ์ฉํ์ ๋์ ๊ฐ์ด ์๋๋์ง ์์ ๋ณ๊ฒฝ์ ๊ฑฑ์ ํ ํ์๋ ์๊ธฐ ๋๋ฌธ์ ๋ ์์ ์ ์ธ ํ๋ก๊ทธ๋๋ฐ์ด ๊ฐ๋ฅํ๋ค.
- ์ด์ฒ๋ผ ํด๋ก์ ๋ ์ํ
state
๊ฐ ์๋์น ์๊ฒ ๋ณ๊ฒฝ๋์ง ์๋๋ก ์์ ํ๊ฒ ์๋information hiding
ํ๊ณ ํน์ ํจ์์๊ฒ๋ง ์ํ ๋ณ๊ฒฝ์ ํ์ฉํ์ฌ ์ํ๋ฅผ ์์ ํ๊ฒ ๋ณ๊ฒฝํ๊ณ ์ ์งํ๊ธฐ ์ํด ์ฌ์ฉํ๋ค.
const counter = (function () {
let num = 0;
return {
increase() {
return ++num;
},
decrease() {
return num > 0 ? --num : 0;
}
};
}());
console.log(counter.increase()); // 1
console.log(counter.increase()); // 2
console.log(counter.decrease()); // 1
console.log(counter.decrease()); // 0
- ์ ์์ ์์ ์ฆ์ ์คํํ๋ ํจ์๊ฐ ๋ฐํํ๋ ๊ฐ์ฒด ๋ฆฌํฐ๋ด์ ์ฆ์ ์คํ ํจ์์ ์คํ ๋จ๊ณ์์ ํ๊ฐ๋์ด ๊ฐ์ฒด๊ฐ ๋๋ค. ์ด๋ ๊ฐ์ฒด์ ๋ฉ์๋๋ ํจ์ ๊ฐ์ฒด๋ก ์์ฑ๋๋ค. ๊ฐ์ฒด ๋ฆฌํฐ๋ด์ ์ค๊ดํธ๋ ์ฝ๋ ๋ธ๋ก์ด ์๋๋ฏ๋ก ๋ณ๋์ ์ค์ฝํ๋ฅผ ์์ฑํ์ง ์๋๋ค.
- ์ ์์ ์ increase, decrease ๋ฉ์๋์ ์์ ์ค์ฝํ๋ ๋ ๋ฉ์๋๊ฐ ํ๊ฐ๋๋ ์์ ์ ์คํ ์ค์ธ ์คํ ์ปจํ ์คํธ์ธ ์ฆ์ ์คํ ํจ์ ์คํ ์ปจํ ์คํธ์ ๋ ์์ปฌ ํ๊ฒฝ์ด๋ค. ๋ฐ๋ผ์ ๋ ๋ฉ์๋๊ฐ ์ธ์ ์ด๋์ ํธ์ถ๋๋ ์๊ด์์ด ์ฆ์ ์คํ ํจ์์ ์ค์ฝํ์ ์๋ณ์๋ฅผ ์ฐธ์กฐํ ์ ์๋ค.
- ์ ์์ ๋ฅผ ์์ฑ์ ํจ์๋ก ํํํ๋ฉด ๋ค์๊ณผ ๊ฐ๋ค.
const Counter = (function(){
let num = 0;
function Counter() {
// this.num = 0; // ํ๋กํผํฐ๋ publicํ๋ฏ๋ก ์๋๋์ง ์๋๋ค.
}
Counter.prototype.increase = function() {
return ++num;
};
Counter.prototype.decrease = function() {
return num > 0 ? --num : 0;
};
return Counter
})();
const counter = new Counter();
console.log(counter.increase()); // 1
console.log(counter.increase()); // 2
console.log(counter.decrease()); // 1
console.log(counter.decrease()); // 0
- ๋ง์ฝ num์ด ์์ฑ์ ํจ์ Counter๊ฐ ์์ฑํ ์ธ์คํด์ค์ ํ๋กํผํฐ๋ผ๋ฉด ์ธ์คํด์ค๋ฅผ ํตํด ์ธ๋ถ์์ ์ ๊ทผ์ด ์์ ๋ก์ด public ํ๋กํผํฐ๊ฐ ๋๋ค. ํ์ง๋ง ์ฆ์ ์คํ ํจ์ ๋ด์์ ์ ์ธ๋ num ๋ณ์๋ ์ธ์คํด์ค๋ฅผ ํตํด ์ ๊ทผํ ์ ์์ผ๋ฉฐ, ์ฆ์ ์คํ ํจ์ ์ธ๋ถ์์๋ ์ ๊ทผํ ์ ์๋ ์๋๋ ๋ณ์๋ค.
- ๋ค์์ ํจ์ํ ํ๋ก๊ทธ๋๋ฐ์์ ํด๋ก์ ๋ฅผ ํ์ฉํ๋ ๊ฐ๋จํ ์์ ๋ค.
// ํจ์๋ฅผ ์ธ์๋ก ์ ๋ฌ๋ฐ๊ณ ํจ์๋ฅผ ๋ฐํํ๋ ๊ณ ์ฐจ ํจ์
// ์ด ํจ์๋ ์นด์ดํธ ์ํ๋ฅผ ์ ์งํ๊ธฐ ์ํ ์์ ๋ณ์ counter๋ฅผ ๊ธฐ์ตํ๋ ํด๋ก์ ๋ฅผ ๋ฐํํ๋ค.
function makeCounter(predicate) {
// ์นด์ดํธ ์ํ๋ฅผ ์ ์งํ๊ธฐ ์ํ ์์ ๋ณ์
let counter = 0;
// ํด๋ก์ ๋ฅผ ๋ฐํ
return function () {
// ์ธ์๋ก ์ ๋ฌ๋ฐ์ ๋ณด์กฐ ํจ์์ ์ํ ๋ณ๊ฒฝ์ ์์ํ๋.
counter = predicate(counter);
return counter
}
}
// ๋ณด์กฐ ํจ์
function increase(n) {
return ++n;
}
// ๋ณด์กฐ ํจ์
function decrease(n) {
return --n;
}
// ํจ์๋ก ํจ์๋ฅผ ์์ฑํ๋ค.
// makeCounter ํจ์๋ ๋ณด์กฐ ํจ์๋ฅผ ์ธ์๋ก ์ ๋ฌ๋ฐ์ ํจ์๋ฅผ ๋ฐํํ๋ค
const increaser = makeCounter(increase);
console.log(increaser()); // 1
console.log(increaser()); // 2
const decreaser = makeCounter(decrease);
console.log(decreaser()); // -1
console.log(decreaser()); // -2
- makerCounter ํจ์๊ฐ ๋ฐํํ๋ ํจ์๋ ์์ ์ด ์์ฑ๋์ ๋์ ๋ ์์ปฌ ํ๊ฒฝ์ธ makeCounter ํจ์์ ์ค์ฝํ์ ์ํ counter ๋ณ์๋ฅผ ๊ธฐ์ตํ๋ ํด๋ก์ ๋ค.
- ์ฃผ์ํด์ผ ํ ๊ฒ์ makeCounter ํจ์๋ฅผ ํธ์ถํด ํจ์๋ฅผ ๋ฐํํ ๋ ๋ฐํ๋ ํจ์๋ ์์ ๋ง์ ๋ ๋ฆฝ๋ ๋ ์์ปฌ ํ๊ฒฝ์ ๊ฐ๋๋ค๋ ๊ฒ์ด๋ค. ํจ์๋ฅผ ํธ์ถํ๋ฉด ๊ทธ๋๋ง๋ค ์๋ก์ด makeCounter ํจ์ ์คํ ์ปจํ ์คํธ์ ๋ ์์ปฌ ํ๊ฒฝ์ ์์ฑ๋๊ธฐ ๋๋ฌธ์ด๋ค.
- ๋ ๋ฆฝ๋ ์นด์ดํฐ๊ฐ ์๋๋ผ ์ฐ๋ํ์ฌ ์ฆ๊ฐ์ด ๊ฐ๋ฅํ ์นด์ดํฐ๋ฅผ ๋ง๋ค๋ ค๋ฉด ๋ ์์ปฌ ํ๊ฒฝ์ ๊ณต์ ํ๋ ํด๋ก์ ๋ฅผ ๋ง๋ค์ด์ผ ํ๋ค. ์ด๋ฅผ ์ํด์๋ makeCounter ํจ์๋ฅผ ๋ ๋ฒ ํธ์ถํ์ง ๋ง์์ผ ํ๋ค.
// ํจ์๋ฅผ ๋ฐํํ๋ ๊ณ ์ฐจ ํจ์
// ์ด ํจ์๋ ์นด์ดํธ ์ํ๋ฅผ ์ ์งํ๊ธฐ ์ํ ์์ ๋ณ์ counter๋ฅผ ๊ธฐ์ตํ๋ ํด๋ก์ ๋ฅผ ๋ฐํํ๋ค.
const counter = (function () {
// ์นด์ดํธ ์ํ๋ฅผ ์ ์งํ๊ธฐ ์ํ ์์ ๋ณ์
let counter = 0;
// ํด๋ก์ ๋ฅผ ๋ฐํ
return function (predicate) {
// ์ธ์๋ก ์ ๋ฌ๋ฐ์ ๋ณด์กฐ ํจ์์ ์ํ ๋ณ๊ฒฝ์ ์์ํ๋.
counter = predicate(counter);
return counter
}
}
// ๋ณด์กฐ ํจ์
function increase(n) {
return ++n;
}
// ๋ณด์กฐ ํจ์
function decrease(n) {
return --n;
}
// ๋ณด์กฐ ํจ์๋ฅผ ์ ๋ฌํ์ฌ ํธ์ถ
console.log(counter(increase)); // 1
console.log(counter(increase)); // 2
// ์์ ๋ณ์๋ฅผ ๊ณต์ ํ๋ค.
console.log(counter(decrease)); // 1
console.log(counter(decrease)); // 0
24.5 ์บก์ํ์ ์ ๋ณด ์๋
- ์บก์ํ
encapsulation
๋ ๊ฐ์ฒด์ ์ํstate
๋ฅผ ๋ํ๋ด๋ ํ๋กํผํฐ์ ํ๋กํผํฐ๋ฅผ ์ฐธ์กฐํ๊ณ ์กฐ์ํ ์ ์๋ ๋์behavior
์ธ ๋ฉ์๋๋ฅผ ํ๋๋ก ๋ฌถ๋ ๊ฒ์ ๋งํ๋ค. ์บก์ํ๋ ๊ฐ์ฒด์ ํน์ ํ๋กํผํฐ๋ ๋ฉ์๋๋ฅผ ๊ฐ์ถ ๋ชฉ์ ์ผ๋ก ์ฌ์ฉํ๊ธฐ๋ ํ๋๋ฐ ์ด๋ฅผ ์ ๋ณด ์๋information hiding
์ด๋ผ ํ๋ค. - ์ ๋ณด ์๋์ ์ธ๋ถ์ ๊ณต๊ฐํ ํ์๊ฐ ์๋ ๊ตฌํ์ ์ผ๋ถ๋ฅผ ์ธ๋ถ์ ๊ณต๊ฐ๋์ง ์๋๋ก ๊ฐ์ถ์ด ์ ์ ์น ๋ชปํ ์ ๊ทผ์ผ๋ก๋ถํฐ ๊ฐ์ฒด์ ์ํ๊ฐ ๋ณ๊ฒฝ๋๋ ๊ฒ์ ๋ฐฉ์งํด ์ ๋ณด๋ฅผ ๋ณดํธํ๊ณ , ๊ฐ์ฒด ๊ฐ์ ์ํธ ์์กด์ฑ, ์ฆ ๊ฒฐํฉ๋
coupling
๋ฅผ ๋ฎ์ถ๋ ํจ๊ณผ๊ฐ ์๋ค. - ๋๋ถ๋ถ์ ๊ฐ์ฒด์งํฅ ํ๋ก๊ทธ๋๋ฐ ์ธ์ด๋ ํด๋์ค๋ฅผ ์ ์ํ๊ณ ๊ทธ ํด๋์ค๋ฅผ ๊ตฌ์ฑํ๋ ๋ฉค๋ฒ(ํ๋กํผํฐ์ ๋ฉ์๋)์ ๋ํ์ฌ public, private, protected ๊ฐ์ ์ ๊ทผ ์ ํ์
access modifier
๋ฅผ ์ ์ธํ์ฌ ๊ณต๊ฐ ๋ฒ์๋ฅผ ํ์ ํ ์ ์๋ค. - ์๋ฐ์คํฌ๋ฆฝํธ๋ public, private, protected ๊ฐ์ ์ ๊ทผ ์ ํ์๋ฅผ ์ ๊ณตํ์ง ์๋๋ค. ๋ฐ๋ผ์ ์๋ฐ์คํฌ๋ฆฝํธ ๊ฐ์ฒด์ ๋ชจ๋ ํ๋กํผํฐ์ ๋ฉ์๋๋ ๊ธฐ๋ณธ์ ์ผ๋ก ์ธ๋ถ์ ๊ณต๊ฐ๋์ด ์๋ค. ์ฆ, ๊ฐ์ฒด์ ๋ชจ๋ ํ๋กํผํฐ์ ๋ฉ์๋๋ ๊ธฐ๋ณธ์ ์ผ๋ก publicํ๋ค.
- ์๋ฐ์คํฌ๋ฆฝํธ๋ ์ ๋ณด ์๋์ ์์ ํ๊ฒ ์ง์ํ์ง ์์์ง๋ง ์๋ก์ด ํ์ค ์ฌ์์ด ๋์๋ค. Private class fields
class Person {
// private ํ๋ ์ ์
#name = '';
constructor(name) {
// private ํ๋ ์ฐธ์กฐ
this.#name = name;
}
}
const me = new Person('Lee');
// private ํ๋ #name์ ํด๋์ค ์ธ๋ถ์์ ์ฐธ์กฐํ ์ ์๋ค.
console.log(me.#name);
// SyntaxError: Private field '#name' must be declared in an enclosing class
- ์ด์ฒ๋ผ ํด๋์ค ์ธ๋ถ์์ private ํ๋์ ์ง์ ์ ๊ทผํ ์ ์๋ ๋ฐฉ๋ฒ์ ์๋ค. ๋ค๋ง ์ ๊ทผ์ ํ๋กํผํฐ๋ฅผ ํตํด ๊ฐ์ ์ ์ผ๋ก ์ ๊ทผํ๋ ๋ฐฉ๋ฒ์ ์ ํจํ๋ค.
class Person {
#name = '';
constructor(name) {
this.#name = name;
}
// name์ ์ ๊ทผ์ ํ๋กํผํฐ๋ค.
get name() {
// private ํ๋๋ฅผ ์ฐธ์กฐํ์ฌ trimํ ๋ค์ ๋ฐํํ๋ค.
return this.#name.trim();
}
}
const me = new Person(' Lee ');
cons
ole.log(me.name); // Lee
- private ํ๋๋ ๋ฐ๋์ ํด๋์ค ๋ชธ์ฒด์ ์ ์ํด์ผ ํ๋ค. private ํ๋๋ฅผ ์ง์ constructor์ ์ ์ํ๋ฉด ์๋ฌ๊ฐ ๋ฐ์ํ๋ค.
class Person {
constructor(name) {
// private ํ๋๋ ํด๋์ค ๋ชธ์ฒด์์ ์ ์ํด์ผ ํ๋ค.
this.#name = name;
// SyntaxError: Private field '#name' must be declared in an enclosing class
}
}
24.6 ์์ฃผ ๋ฐ์ํ๋ ์ค์
- ์๋๋ ํด๋ก์ ๋ฅผ ์ฌ์ฉํ ๋ ์์ฃผ ๋ฐ์ํ ์ ์๋ ์ค์๋ฅผ ๋ณด์ฌ์ฃผ๋ ์์ ๋ค.
var funcs = [];
for (var i = 0; i < 3; i++) {
funcs[i] = function () { return i; };
}
for (var j = 0; j < funcs.length; j++) {
console.log(funcs[j]());
}
// 3
// 3
// 3
-
var ํค์๋๋ก ์ ์ธํ i ๋ณ์๋ ๋ธ๋ก ๋ ๋ฒจ ์ค์ฝํ๊ฐ ์๋ ํจ์ ๋ ๋ฒจ ์ค์ฝํ๋ฅผ ๊ฐ๊ธฐ ๋๋ฌธ์ ์ ์ญ ๋ณ์๋ค. ๋ฐ๋ผ์ funcs ๋ฐฐ์ด์ ์์๋ก ์ถ๊ฐํ ํจ์๋ฅผ ํธ์ถํ๋ฉด ์ ์ญ ๋ณ์ i๋ฅผ ์ฐธ์กฐํ์ฌ i์ ๊ฐ 3์ด ์ถ๋ ฅ๋๋ค.
-
ํด๋ก์ ๋ฅผ ์ฌ์ฉํด ์ ์์ ๋ฅผ ๋ฐ๋ฅด๊ฒ ๋์ํ๋ ์ฝ๋๋ก ๋ง๋ค์ด ๋ณด์.
var funcs = [];
for (var i = 0; i < 3; i++) {
funcs[i] = (function (id) {
return function() {
return id;
};
}(i));
}
for (var j = 0; j < funcs.length; j++) {
console.log(funcs[j]());
}
// 0
// 1
// 2
- ES6์ let ํค์๋๋ฅผ ์ฌ์ฉํ๋ฉด ๋ ๊น๋ํ๊ฒ ํด๊ฒฐ๋๋ค.
var funcs = [];
for (let i = 0; i < 3; i++) {
funcs[i] = function () { return i; };
}
for (let j = 0; j < funcs.length; j++) {
console.log(funcs[j]());
}