ํฐ์คํ ๋ฆฌ ๋ทฐ
[JavaScript] ํด๋ก์
๊ฐ๋ฐ๊ฐ๊ตด๐ธ 2022. 7. 27. 22:39ํด๋ก์ (closure)๋ ์๋ฐ์คํฌ๋ฆฝํธ ๊ณ ์ ์ ๊ฐ๋ ์ด ์๋ ํจ์ํ ํ๋ก๊ทธ๋๋ฐ ์ธ์ด์์ ์ฌ์ฉ๋๋ ์ค์ํ ํน์ฑ์ผ๋ก MDN์์๋ ํด๋ก์ ๋ฅผ "ํจ์์ ๊ทธ ํจ์๊ฐ ์ ์ธ๋ ๋ ์์ปฌ ํ๊ฒฝ๊ณผ์ ์กฐํฉ"์ด๋ผ๊ณ ์ ์ํฉ๋๋ค.
๋ฐ๋ผ์ ํด๋ก์ ๋ฅผ ์ดํดํ๊ธฐ ์ํด์ ํจ์๊ฐ ์ ์ธ๋ ๋ ์์ปฌ ํ๊ฒฝ์ ๋ํด ์์์ผํฉ๋๋ค.
๋ ์์ปฌ ์ค์ฝํ
์๋ฐ์คํฌ๋ฆฝํธ ์์ง์ ํจ์๋ฅผ ์ด๋์ ์ ์ํ๋์ง์ ๋ฐ๋ผ ์์ ์ค์ฝํ์ธ ๋ ์์ปฌ ์ค์ฝํ(์ ์ ์ค์ฝํ)๋ฅผ ๊ฒฐ์ ํฉ๋๋ค.
const x = 1;
function foo () {
const x = 10;
bar();
}
function bar () {
console.log(X);
}
foo(); // 1
bar(); // 1
์ ์์ ์ foo ํจ์์ bar ํจ์๋ ๋ชจ๋ ์ ์ญ์์ ์ ์๋ ์ ์ญ ํจ์๋ก foo ํจ์์ bar ํจ์ ๋ชจ๋ ์์ ์ค์ฝํ๋ ์ ์ญ์ ๋๋ค.
์ฆ, ํจ์์ ์์ ์ค์ฝํ๋ ํจ์๋ฅผ ์ ์ํ ์์น์ ์ํด ์ ์ ์ผ๋ก ๊ฒฐ์ ๋๊ณ ๋ณํ์ง ์์ต๋๋ค.
๋ฐ๋ผ์ ๋ ์์ปฌ ์ค์ฝํ๋ ๋ ์์ปฌ ํ๊ฒฝ์ "์ธ๋ถ ๋ ์์ปฌ ํ๊ฒฝ์ ๋ํ ์ฐธ์กฐ"์ ์ ์ฅํ ์ฐธ์กฐ๊ฐ, ์ฆ ์์ ์ค์ฝํ์ ๋ํ ์ฐธ์กฐ๋ ํจ์ ์ ์๊ฐ ํ๊ฐ๋๋ ์์ ์ ํจ์๊ฐ ์ ์๋ ํ๊ฒฝ(์์น)์ ์ํด ๊ฒฐ์ ๋ฉ๋๋ค.
ํจ์ ๊ฐ์ฒด์ ๋ด๋ถ ์ฌ๋กฏ [[Environment]]
ํจ์๋ ์์ ์ ๋ด๋ถ ์ฌ๋กฏ [[Environment]]์ ์์ ์ด ์ ์๋ ํ๊ฒฝ, ์ฆ ์์ ์ค์ฝํ์ ์ฐธ์กฐ๋ฅผ ์ ์ฅํ์ฌ ํจ์๊ฐ ํธ์ถ๋๋ ํ๊ฒฝ๊ณผ๋ ์๊ด์์ด ์์ ์ด ์ ์๋ ํ๊ฒฝ์ ๊ธฐ์ตํฉ๋๋ค.
const x = 1;
function foo () {
const x = 10;
// ์์ ์ค์ฝํ๋ ํจ์ ์ ์ ํ๊ฒฝ(์์น)์ ๋ฐ๋ผ ๊ฒฐ์
// ํจ์ ํธ์ถ ์์น์ ์์ ์ค์ฝํ๋ ์๋ฌด๋ฐ ๊ด๊ณ๊ฐ ์์
bar();
}
// ํจ์ bar๋ ์์ ์ ์์ ์ค์ฝํ, ์ฆ ์ ์ญ ๋ ์์ปฌ ํ๊ฒฝ์ [[Environment]]์ ์ ์ฅํ์ฌ ๊ธฐ์ต
function bar () {
console.log(X);
}
foo(); // 1
bar(); // 1
์ ์์ ์์ barํจ์๊ฐ ์ ์ญ ๋ ์์ปฌ ํ๊ฒฝ์ ์ ์ฅํ์ฌ ๊ธฐ์ตํ๋ ๊ฒ์ฒ๋ผ ์์ ์ ๋ด๋ถ ์ฌ๋กฏ [[Environment]]์ ์ ์ฅ๋ ์์ ์ค์ฝํ์ ์ฐธ์กฐ๋ ํ์ฌ ์คํ ์ค์ธ ์คํ ์ปจํ ์คํธ์ ๋ ์์ปฌ ํ๊ฒฝ์ ๊ฐ๋ฆฌํค๋ ๊ฒ์ ์ ์ ์์ต๋๋ค.
ํด๋ก์ ์ ๋ ์์ปฌ ํ๊ฒฝ
์ธ๋ถ ํจ์๋ณด๋ค ์ค์ฒฉ ํจ์๊ฐ ๋ ์ค๋ ์ ์ง๋๋ ๊ฒฝ์ฐ ์ค์ฒฉ ํจ์๋ ์ด๋ฏธ ์๋ช ์ฃผ๊ธฐ๊ฐ ์ข ๋ฃํ ์ธ๋ถ ํจ์์ ๋ณ์๋ฅผ ์ฐธ์กฐํ ์ ์๋๋ฐ ์ด๋ฌํ ์ค์ฒฉ ํจ์๋ฅผ ํด๋ก์ ๋ผ๊ณ ๋ถ๋ฆ ๋๋ค.
const x = 1;
function outer () {
const x = 10;
const inner = function () { console.log(x); };
return inner;
}
// outer ํจ์๋ฅผ ํธ์ถํ๋ฉด ์ค์ฒฉ ํจ์ inner๋ฅผ ๋ฐํ
const innerFunc = outer();
innerFunc(); // 10
- outer ํจ์๋ฅผ ํธ์ถํ๋ฉด outer ํจ์๋ ์ค์ฒฉ ํจ์ inner๋ฅผ ๋ฐํํ๊ณ ์๋ช ์ฃผ๊ธฐ๋ฅผ ๋ง๊ฐ
- outer ํจ์์ ์คํ ์ปจํ ์คํธ(์ง์ญ ๋ณ์ x์ ๋ณ์ ๊ฐ 10์ด ์ ์ฅ๋์ด ์์)๋ ์คํ ์ปจํ ์คํธ ์คํ์์ ์ ๊ฑฐ๋จ
- outer ํจ์์ ๋ ์์ปฌ ํ๊ฒฐ๊น์ง ์๋ฉธํ๋ ๊ฒ์ ์๋๊ธฐ ๋๋ฌธ์ innerFunc์ 10์ ๋ฐํํจ
์ ์์ ๋ฅผ ํตํด inner๋ ์ธ๋ถ ํจ์์ ์์กด ์ฌ๋ถ์ ์๊ด์์ด ์์ ์ด ์ ์๋ ์์น์ ์ํด ๊ฒฐ์ ๋ ์์ ์ค์ฝํ๋ฅผ ๊ธฐ์ตํ๊ณ ์๋ ๊ฒ์ ์ ์ ์์ต๋๋ค. ์ด์ฒ๋ผ ์ค์ฒจ ํจ์ inner ๋ด๋ถ์์๋ ์์ ์ค์ฝํ๋ฅผ ์ฐธ์กฐํ ์ ์์ผ๋ฏ๋ก ์์ ์ค์ฝํ์ ์๋ณ์๋ฅผ ์ฐธ์กฐํ ์ ์๊ณ ์๋ณ์์ ๊ฐ์ ๋ณ๊ฒฝํ ์ ์์ต๋๋ค.
์๋ฐ์คํฌ๋ฆฝํธ์ ๋ชจ๋ ํจ์๋ ์์ ์ค์ฝํ๋ฅผ ๊ธฐ์ตํ๋ฏ๋ก ์ด๋ก ์ ์ผ๋ก ๋ชจ๋ ํจ์๋ ํด๋ก์ ์ด์ง๋ง, ์์ ์ค์ฝํ์ ์๋ณ์๋ฅผ ์ฐธ์กฐํ์ง ์๋๋ค๋ฉด ๋ชจ๋ ๋ธ๋ผ์ฐ์ ๋ ์ต์ ํ๋ฅผ ํตํด ์์ ์ค์ฝํ๋ฅผ ๊ธฐ์ตํ์ง ์๊ธฐ ๋๋ฌธ์ ํด๋ก์ ๋ผ๊ณ ํ์ง ์์ต๋๋ค.
๋ฐ๋ผ์ ํด๋ก์ ๋ ์ค์ฒฉ ํจ์๊ฐ ์์ ์ค์ฝํ์ ์๋ณ์๋ฅผ ์ฐธ์กฐํ๊ณ ์๊ณ ์ค์ฒฉ ํจ์๊ฐ ์ธ๋ถ ํจ์๋ณด๋ค ๋ ์ค๋ ์ ์ง๋๋ ๊ฒฝ์ฐ์ ํ์ ํ๋ ๊ฒ์ด ์ผ๋ฐ์ ์ ๋๋ค.
ํด๋ก์ ์ ํ์ฉ
ํด๋ก์ ๋ ์ํ๋ฅผ ์์ ํ๊ฒ ๋ณ๊ฒฝํ๊ณ ์ ์งํ๊ธฐ ์ํด์ ์ฌ์ฉ๋ฉ๋๋ค.
ํด๋ก์ ๋ฅผ ํ์ฉํด ์ํ๋ฅผ ์์ ํ๊ฒ ๋ณ๊ฒฝํ๊ณ ์ ์งํ๋ ์์ ๋ ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
// ์นด์ดํธ ์ํ ๋ณ๊ฒฝ ํจ์
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์ ์ธ์ ์ด๋์ ํธ์ถํ๋ ์ง ์ฐธ์กฐ/๋ณ๊ฒฝ์ด ๊ฐ๋ฅ
์ด์ฒ๋ผ ํด๋ก์ ๋ ์ํ๊ฐ ์๋์น ์๊ฒ ๋ณ๊ฒฝ๋์ง ์๋๋ก ์ํ๋ฅผ ์์ ํ๊ฒ ์๋ํ๊ณ ํน์ ํจ์์๊ฒ๋ง ์ํ ๋ณ๊ฒฝ์ ํ์ฉํ์ฌ ์ํ๋ฅผ ์์ ํ๊ฒ ๋ณ๊ฒฝํ๊ณ ์ ์งํ๊ธฐ ์ํด ์ฌ์ฉํฉ๋๋ค.
๋ํ, ์ธ๋ถ ์ํ ๋ณ๊ฒฝ์ด๋ ๊ฐ๋ณ ๋ฐ์ดํฐ๋ฅผ ํผํ๊ณ ๋ถ๋ณ์ฑ์ ์งํฅํ๋ ํจ์ํ ํ๋ก๊ทธ๋๋ฐ์์ ๋ถ์ ํจ๊ณผ๋ฅผ ์ต๋ํ ์ต์ ํ์ฌ ์ค๋ฅ๋ฅผ ํผํ๊ณ ํ๋ก๊ทธ๋จ์ ์์ ์ฑ์ ๋์ด๊ธฐ ์ํด ํด๋ก์ ๋ ์ ๊ทน์ ์ผ๋ก ํ์ฉ๋ฉ๋๋ค.
// ํจ์๋ฅผ ๋ฐํํ๋ ๊ณ ์ฐจ ํจ์
// ์นด์ดํธ ์ํ๋ฅผ ์ ์งํ๊ธฐ ์ํ ์์ ๋ณ์ counter๋ฅผ ๊ธฐ์ตํ๋ ํด๋ก์ ๋ฅผ ๋ฐํ
const couter = (function () {
// ์นด์ดํธ ์ํ๋ฅผ ์ ์งํ๊ธฐ ์ํ ์์ ๋ณ์
let counter = 0;
// ํจ์๋ฅผ ์ธ์๋ก ์ ๋ฌ๋ฐ๋ ํด๋ก์ ๋ฅผ ๋ฐํ
return function (aux) {
// ์ธ์๋ก ์ ๋ฌ๋ฐ์ ๋ณด์กฐ ํจ์์ ์ํ ๋ณ๊ฒฝ์ ์์
counter = aux(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
์ ์์ ์ฒ๋ผ ๋ ์์ปฌ ํ๊ฒฝ์ ๊ณต์ ํ๋ ํด๋ก์ ๋ฅผ ๋ง๋ค์ด ์ฐ๋ํ์ฌ ์ฆ๊ฐ์ด ๊ฐ๋ฅํ ์นด์ดํฐ๋ฅผ ๋ง๋ค ์ ์์ต๋๋ค.
์บก์ํ์ ์ ๋ณด ์๋
์บก์ํ๋ฅผ ํตํด ์ ๋ณด ์๋์ ํ๋ฉด ์ ์ ์น ๋ชปํ ์ ๊ทผ์ผ๋ก๋ถํฐ ๊ฐ์ฒด์ ์ํ๊ฐ ๋ณ๊ฒฝ๋๋ ๊ฒ์ ๋ฐฉ์งํด ์ ๋ณด๋ฅผ ๋ณดํธํ๊ณ , ๊ฐ์ฒด ๊ฐ์ ์ํธ ์์กด์ฑ(๊ฒฐํฉ๋)๋ฅผ ๋ฎ์ถ๋ ํจ๊ณผ๊ฐ ์์ต๋๋ค.
- ์บก์ํ : ๊ฐ์ฒด์ ์ํ๋ฅผ ๋ํ๋ด๋ ํ๋กํผํฐ๋ฅผ ์ฐธ์กฐํ๊ณ ์กฐ์ํ ์ ์๋ ๋์์ธ ๋ฉ์๋๋ฅผ ํ๋๋ก ๋ฌถ๋ ๊ฒ
- ์ ๋ณด ์๋ : ์บก์ํ๋ฅผ ํตํด ๊ฐ์ฒด์ ํน์ ํ๋กํผํฐ๋ ๋ฉ์๋๋ฅผ ๊ฐ์ถ ๋ชฉ์ ์ผ๋ก ์ฌ์ฉํ๋ ๊ฒ
๋๋ถ๋ถ์ ๊ฐ์ฒด์งํฅ ํ๋ก๊ทธ๋๋ฐ ์ธ์ด๋ ์ ๊ทผ ์ ํ์(public, private, protected)๋ฅผ ํตํด ๊ณต๊ฐ ๋ฒ์๋ฅผ ํ์ ํ ์ ์์ง๋ง, ์๋ฐ์คํฌ๋ฆฝํธ ์ ๊ทผ ์ ํ์๋ฅผ ์ ๊ณตํ์ง ์์์ ๊ฐ์ฒด์ ๋ชจ๋ ํ๋กํผํฐ์ ๋ฉ์๋๋ ๊ธฐ๋ณธ์ ์ผ๋ก ์ธ๋ถ์ ๊ณต๊ฐ๋์ด ์์ต๋๋ค.
ํ์ง๋ง, ์๋ฐ์คํฌ๋ฆฝํธ๋ ๋ค์๊ณผ ๊ฐ์ ํจํด์ ํตํด ์ ๋ณด ์๋์ด ๊ฐ๋ฅํ ๊ฒ์ฒ๋ผ ๋ณด์ด๊ฒ ํ ์ ์์ต๋๋ค.
const Person = (function () {
let _age = 0; // private
// ์์ฑ์ ํจ์
function Person(name, age) {
this.name = name; // public
_age = age;
}
// ํ๋กํ ํ์
๋ฉ์๋
Person.prototype.sayHi = function () {
console.log(`Hi! My name is ${this.name}. I am ${_age}.`);
};
// ์์ฑ์ ํจ์๋ฅผ ๋ฐํ
return Person;
}());
const me = new Person('Lee', 20);
me.sayHi(); // Hi! My name is Lee. I am 20.
console.log(me.name); // Lee
console.log(me._age); // undefined
const you = new Person('Kim', 30);
you.sayHi(); // Hi! My name is Kim. I am 30.
console.log(me.name); // Kim
console.log(me._age); // undefined
์ ์์ ์ _age ๋ณ์๋ Person ์์ฑ์ ํจ์์ ์ง์ญ ๋ณ์์ด๋ฏ๋ก Person ์์ฑ์ ํจ์ ์ธ๋ถ์์ ์ฐธ์กฐ/๋ณ๊ฒฝ ํ ์ ์์ด privateํฉ๋๋ค. ๋ํ, Person.prototype.sayHi ๋ฉ์๋๋ ์ฆ์ ์คํ ํจ์๊ฐ ์ข ๋ฃ๋ ์ดํ ํธ์ถ๋์ง๋ง Person ์์ฑ์ ํจ์์ sayHi ๋ฉ์๋๋ ์ด๋ฏธ ์ข ๋ฃ๋์ด ์๋ฉธํ ์ฆ์ ์คํ ํจ์์ ์ง์ญ ๋ณ์ _age๋ฅผ ์ฐธ์กฐํ ์ ์๋ ํด๋ก์ ์ ๋๋ค.
Person.prototype.sayHi ๋ฉ์๋๋ ๋จ ํ๋ฒ ์์ฑ๋๋ ํด๋ก์ ์ด๊ธฐ ๋๋ฌธ์ Person ์์ฑ์ ํจ์๊ฐ ์ฌ๋ฌ ๊ฐ์ ์ธ์คํด์ค๋ฅผ ์์ฑํ ๊ฒฝ์ฐ _age๋ณ์์ ์ํ๊ฐ ์ ์ง๋์ง๋ ์์ต๋๋ค.
์ด์ฒ๋ผ ์๋ฐ์คํฌ๋ฆฝํธ๋ ์ ๋ณด ์๋์ ์์ ํ๊ฒ๋ ์ง์ํ์ง ์์ต๋๋ค.
[์ถ์ฒ] ๋ชจ๋ ์๋ฐ์คํฌ๋ฆฝํธ Deep Dive
'JavaScript > ๋ชจ๋ ์๋ฐ์คํฌ๋ฆฝํธ Deep Dive' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[JavaScript] ES6 ํจ์์ ์ถ๊ฐ ๊ธฐ๋ฅ (0) | 2022.07.29 |
---|---|
[JavaScript] ํด๋์ค (0) | 2022.07.28 |
[JavaScript] ์คํ ์ปจํ ์คํธ (0) | 2022.07.27 |
[JavaScript] this (0) | 2022.07.26 |
[JavaScript] ๋นํธ์ธ ๊ฐ์ฒด (0) | 2022.07.25 |
- Total
- Today
- Yesterday
- ๋์์ธ ํจํด
- ์๋ฐ
- 2019 ์นด์นด์ค ๊ฐ๋ฐ์ ๊ฒจ์ธ ์ธํด
- ๋ฐฑ์ค node.js
- ๋ฐฑ์ค javascript
- ์นด์นด์ค ์ธํด
- TDD
- ์ด์์ฒด์
- ์๊ณ ๋ฆฌ์ฆ
- ํ๋กํ ์ฝ
- ๋ ์์ปฌ ํ๊ฒฝ
- ์ ์ญ ๋ณ์
- ๋ชจ๋ ์๋ฐ์คํฌ๋ฆฝํธ deep dive
- ๊ฐ์ฒด์งํฅ ํ๋ก๊ทธ๋๋ฐ
- Baekjoon
- ํ๋กํผํฐ
- ํ๋ก๊ทธ๋๋จธ์ค
- git
- ์ด๋ถํ์
- ํฌํฌ์ธํฐ
- fp
- JavaScript
- ๋ฐฑ์ค
- ํจ์ํ ํ๋ก๊ทธ๋๋ฐ
- ๋คํธ์ํฌ
- http
- map
- ์๋ฐ์คํฌ๋ฆฝํธ
- ์ฝ๋ฉํ ์คํธ
- ๋ค์ด๋๋ฏน ํ๋ก๊ทธ๋๋ฐ
์ผ | ์ | ํ | ์ | ๋ชฉ | ๊ธ | ํ |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |