์ฃผ๋‹ˆ์–ด ๊ฐœ๋ฐœ์ž์˜ ๊ฐœ์ธ ๊ณต๋ถ€ ๊ณผ์ •์„ ๊ธฐ๋กํ•ฉ๋‹ˆ๋‹ค.

ํด๋กœ์ €(Closure)๋Š” (์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ๊ณ ์œ  ๊ฐœ๋…์ด ์•„๋‹Œ) ํ•จ์ˆ˜ํ˜• ํ”„๋กœ๊ทธ๋ž˜๋ฐ ์–ธ์–ด์—์„œ ๋“ฑ์žฅํ•˜๋Š” ํŠน์„ฑ ์ค‘ ํ•˜๋‚˜์ด๋‹ค.

ํ•˜์ง€๋งŒ ํด๋กœ์ €๋Š” ๊ฐ์ฒด์ง€ํ–ฅ๊ณผ ํ•จ์ˆ˜ํ˜• ๋ชจ๋‘๋ฅผ ์•„์šฐ๋ฅด๋Š” ๋งค์šฐ ์ค‘์š”ํ•œ ๊ฐœ๋…์ด๊ณ ,

์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๋ฅผ ์ด์šฉํ•œ ๊ณ ๋‚œ์ด๋„์˜ ํ…Œํฌ๋‹‰์„ ๊ตฌ์‚ฌํ•˜๋Š”๋ฐ ํ•„์ˆ˜์ ์ธ ๊ฐœ๋…์œผ๋กœ ํ™œ์šฉ๋œ๋‹ค.


ํด๋กœ์ €(Closure)๋ž€?

ํด๋กœ์ €(closure)๋Š” ๋‚ด๋ถ€ํ•จ์ˆ˜๊ฐ€ ์™ธ๋ถ€ํ•จ์ˆ˜์˜ ๋งฅ๋ฝ(context)์— ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๋Š” ๊ฒƒ์„ ๊ฐ€๋ฅดํ‚จ๋‹ค.

์ฆ‰, ํด๋กœ์ €๋Š” ์™ธ๋ถ€ํ•จ์ˆ˜์˜ ์ปจํ…์ŠคํŠธ์— ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๋Š” ๋‚ด๋ถ€ํ•จ์ˆ˜๋ฅผ ๋œปํ•œ๋‹ค.

:: ๋‚ด๋ถ€ํ•จ์ˆ˜

ํ•จ์ˆ˜ ์•ˆ์— ์„ ์–ธ๋œ ๋˜ ๋‹ค๋ฅธ ํ•จ์ˆ˜. ์ฆ‰ ์•„๋ž˜ ์ฝ”๋“œ์˜ inner()๋ฅผ ๊ฐ€๋ฆฌํ‚จ๋‹ค.

const outer = () => {
  let a = 1;
  const inner = () => {
    return ++a;
  };
  return inner;
};

const outer2 = outer();
console.log(outer2()); // 2
console.log(outer2()); // 3

ํ•จ์ˆ˜์˜ ์‹คํ–‰ ์ปจํ…์ŠคํŠธ๊ฐ€ ์ข…๋ฃŒ๋œ ํ›„์—๋„ LexicalEnvironment๊ฐ€ ๊ฐ€๋น„์ง€ ์ปฌ๋ ‰ํ„ฐ์˜ ์ˆ˜์ง‘ ๋Œ€์ƒ์—์„œ ์ œ์™ธ๋˜๋Š” ๊ฒฝ์šฐ๋Š”, ์ง€์—ญ๋ณ€์ˆ˜๋ฅผ ์ฐธ์กฐํ•˜๋Š” ๋‚ด๋ถ€ํ•จ์ˆ˜๊ฐ€ ์™ธ๋ถ€๋กœ ์ „๋‹ฌ๋œ ๊ฒฝ์šฐ๊ฐ€ ์œ ์ผํ•˜๋‹ค.

๊ฐ€๋น„์ง€ ์ปฌ๋ ‰ํ„ฐ๋Š” ์–ด๋–ค ๊ฐ’์„ ์ฐธ์กฐํ•˜๋Š” ๋ณ€์ˆ˜๊ฐ€ ํ•˜๋‚˜๋ผ๋„ ์žˆ๋‹ค๋ฉด ๊ทธ ๊ฐ’์€ ์ˆ˜์ง‘ ๋Œ€์ƒ์—์„œ ์ œ์™ธ์‹œํ‚จ๋‹ค.

์ด๋Ÿฐ ํ˜„์ƒ์œผ๋กœ ๋‹ค์‹œ ํด๋กœ์ €๋ฅผ ์ •์˜ํ•˜๋ฉด,

ํด๋กœ์ €๋ž€? ์–ด๋–ค ํ•จ์ˆ˜ A์—์„œ ์„ ์–ธํ•œ ๋ณ€์ˆ˜ a๋ฅผ ์ฐธ์กฐํ•˜๋Š” ๋‚ด๋ถ€ํ•จ์ˆ˜ B๋ฅผ ์™ธ๋ถ€๋กœ ์ „๋‹ฌํ•  ๊ฒฝ์šฐ, A์˜ ์‹คํ–‰ ์ปจํ…์ŠคํŠธ๊ฐ€ ์ข…๋ฃŒ๋œ ์ดํ›„์—๋„ ๋ณ€์ˆ˜ a๊ฐ€ ์‚ฌ๋ผ์ง€์ง€ ์•Š๋Š” ํ˜„์ƒ์„ ๋งํ•œ๋‹ค

๋‚ด๋ถ€ํ•จ์ˆ˜๋ฅผ ์™ธ๋ถ€๋กœ ์ „๋‹ฌํ•˜๋Š” ๋ฐฉ๋ฒ•์—๋Š” ํ•จ์ˆ˜๋ฅผ returnํ•˜๋Š” ๊ฒฝ์šฐ๋ฟ ์•„๋‹ˆ๋ผ, ์ฝœ๋ฐฑ์œผ๋กœ ์ „๋‹ฌํ•˜๋Š” ๊ฒฝ์šฐ๋„ ํฌํ•จ๋œ๋‹ค.



ํด๋กœ์ €์™€ ๋ฉ”๋ชจ๋ฆฌ ๊ด€๋ฆฌ

ํด๋กœ์ €๋Š” ๊ทธ ๋ณธ์งˆ์ด ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ๊ณ„์† ์ฐจ์ง€ํ•˜๋Š” ๊ฐœ๋…์ด๋ฏ€๋กœ ๋” ์ด์ƒ ์‚ฌ์šฉํ•˜์ง€ ์•Š๊ฒŒ ๋œ ํด๋กœ์ €๋Š” ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ์ฐจ์ง€ํ•˜์ง€ ์•Š๋„๋ก ๊ด€๋ฆฌํ•ด์ฃผ์–ด์•ผ ํ•œ๋‹ค.

๊ด€๋ฆฌ ๋ฐฉ๋ฒ•์€ ์ฐธ์กฐ ์นด์šดํŠธ๋ฅผ 0์œผ๋กœ ๋งŒ๋“ค๋ฉด ๊ฐ€๋น„์ง€ ์ปฌ๋ ‰ํ„ฐ๊ฐ€ ์ˆ˜๊ฑฐํ•  ํ…๋ฐ, ์ฐธ์กฐ ์นด์šดํŠธ๋ฅผ 0์œผ๋กœ ๋งŒ๋“œ๋Š” ๋ฐฉ๋ฒ•์€

์‹๋ณ„์ž์— ์ฐธ์กฐํ˜•์ด ์•„๋‹Œ ๊ธฐ๋ณธํ˜• ๋ฐ์ดํ„ฐ(๋ณดํ†ต null ๋˜๋Š” undefined)๋ฅผ ํ• ๋‹นํ•˜๋ฉด ๋œ๋‹ค.

const outer = () => {
  let a = 1;
  const inner = () => {
    return ++a;
    inner = null; // inner ์‹๋ณ„์ž์˜ ํ•จ์ˆ˜ ์ฐธ์กฐ๋ฅผ ๋Š์Œ
  };
  return inner;
};

console.log(outer());
console.log(outer());
outer = null; // outer ์‹๋ณ„์ž์˜ inner ํ•จ์ˆ˜ ์ฐธ์กฐ๋ฅผ ๋Š์Œ

โœจ tl;dr

  • ํด๋กœ์ €๋ž€ ์–ด๋–ค ํ•จ์ˆ˜์—์„œ ์„ ์–ธํ•œ ๋ณ€์ˆ˜๋ฅผ ์ฐธ์กฐํ•˜๋Š” ๋‚ด๋ถ€ํ•จ์ˆ˜๋ฅผ ์™ธ๋ถ€๋กœ ์ „๋‹ฌํ•  ๊ฒฝ์šฐ, ํ•จ์ˆ˜์˜ ์‹คํ–‰ ์ปจํ…์ŠคํŠธ๊ฐ€ ์ข…๋ฃŒ๋œ ํ›„์—๋„ ํ•ด๋‹น ๋ณ€์ˆ˜๊ฐ€ ์‚ฌ๋ผ์ง€์ง€ ์•Š๋Š” ํ˜„์ƒ์ด๋‹ค.

  • ๋‚ด๋ถ€ํ•จ์ˆ˜๋ฅผ ์™ธ๋ถ€๋กœ ์ „๋‹ฌํ•˜๋Š” ๋ฐฉ๋ฒ•์—๋Š” ํ•จ์ˆ˜๋ฅผ returnํ•˜๋Š” ๊ฒฝ์šฐ๋ฟ ์•„๋‹ˆ๋ผ, ์ฝœ๋ฐฑ์œผ๋กœ ์ „๋‹ฌํ•˜๋Š” ๊ฒฝ์šฐ๋„ ํฌํ•จ๋œ๋‹ค.

  • ํด๋กœ์ €๋Š” ๊ทธ ๋ณธ์งˆ์ด ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ๊ณ„์† ์ฐจ์ง€ํ•˜๋Š” ๊ฐœ๋…์ด๋ฏ€๋กœ ๋” ์ด์ƒ ์‚ฌ์šฉํ•˜์ง€ ์•Š๊ฒŒ ๋œ ํด๋กœ์ €๋Š” ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ์ฐจ์ง€ํ•˜์ง€ ์•Š๋„๋ก ๊ด€๋ฆฌํ•ด์•ผ ํ•œ๋‹ค.