JS closure

werthersΒ·2025λ…„ 3μ›” 28일

JavaScript

λͺ©λ‘ 보기
1/3
post-thumbnail

πŸ“Œ JavaScript ν΄λ‘œμ €

🧠 ν΄λ‘œμ €(Closure)λž€?

ν΄λ‘œμ €λŠ” ν•¨μˆ˜μ™€ κ·Έ ν•¨μˆ˜κ°€ μ„ μ–Έλœ λ ‰μ‹œμ»¬ ν™˜κ²½μ˜ μ‘°ν•©
ν•¨μˆ˜ λ‚΄λΆ€μ—μ„œ μ™ΈλΆ€ ν•¨μˆ˜μ˜ λ³€μˆ˜μ— μ ‘κ·Όν•  수 μžˆλ„λ‘ λ§Œλ“œλŠ” κΈ°λŠ₯
μžλ°”μŠ€ν¬λ¦½νŠΈμ—μ„œλŠ” ν•¨μˆ˜κ°€ 평가될 λ•Œμ˜ μƒμœ„ μŠ€μ½”ν”„ 체인도 참쑰함. (μ™ΈλΆ€ λ ‰μ‹œμ»¬ ν™˜κ²½ 참쑰에 λŒ€ν•œ κ²°μ •)


πŸ“¦ λ ‰μ‹œμ»¬ μŠ€μ½”ν”„(Lexical Scope)λž€?

λ ‰μ‹œμ»¬(Lexical) μŠ€μ½”ν”„λŠ” 정적 μŠ€μ½”ν”„λΌκ³ λ„ 뢈리며, ν•¨μˆ˜κ°€ μ–΄λ””μ„œ μ •μ˜λ˜μ—ˆλŠ”μ§€μ— 따라 μƒμœ„ μŠ€μ½”ν”„κ°€ κ²°μ •λ˜λŠ” 방식.
μ‹€ν–‰λ˜λŠ” μœ„μΉ˜κ°€ μ•„λ‹ˆλΌ μ •μ˜λœ μœ„μΉ˜κ°€ κΈ°μ€€μ΄λΌλŠ” 점이 핡심.

λ˜ν•œ, ν•¨μˆ˜ 객체 λ‚΄λΆ€ 슬둯 [[Environment]]에 μ €μž₯함.
ν•¨μˆ˜ μžμ‹ μ΄ μ •μ˜λœ ν™˜κ²½μΈ μƒμœ„ μŠ€μ½”ν”„μ˜ μ°Έμ‘°λ₯Ό μ €μž₯
즉, ν•¨μˆ˜κ°€ 평가될 λ‹Ήμ‹œμ˜ μ‹€ν–‰ 쀑인 μ‹€ν–‰ μ»¨ν…μŠ€νŠΈμ˜ λ ‰μ‹œμ»¬ ν™˜κ²½μ„ κ°€λ₯΄ν‚΄.


πŸ§ͺ ν΄λ‘œμ € μ˜ˆμ‹œ

function outer() {
  const x = 10;

  const inner = function() {
    console.log(x); // μ™ΈλΆ€ ν•¨μˆ˜μ˜ λ³€μˆ˜ x에 μ ‘κ·Ό
  };

  return inner;
}

const closureFn = outer();
closureFn(); // κ²°κ³Ό: 10

이 μ˜ˆμ œμ—μ„œ outer()λŠ” λ‚΄λΆ€ ν•¨μˆ˜ innerλ₯Ό λ°˜ν™˜ν•˜κ³  μ’…λ£Œλ˜μ§€λ§Œ, innerλŠ” μ—¬μ „νžˆ xλ₯Ό κΈ°μ–΅ν•˜κ³  있음.

이게 ν΄λ‘œμ €μ΄λ‹€.


πŸ” μ™ΈλΆ€ ν•¨μˆ˜λ³΄λ‹€ 였래 μ‚΄μ•„λ‚¨λŠ” 쀑첩 ν•¨μˆ˜

μ€‘μš”ν•œ κ°œλ…

쀑첩 ν•¨μˆ˜κ°€ μ™ΈλΆ€ ν•¨μˆ˜λ³΄λ‹€ 였래 μƒμ‘΄ν•˜λ©΄μ„œ μ™ΈλΆ€ ν•¨μˆ˜μ˜ μ§€μ—­ λ³€μˆ˜λ₯Ό μ°Έμ‘°ν•˜λ©΄ ν΄λ‘œμ €κ°€ λ§Œλ“€μ–΄μ§€κ³ , μ™ΈλΆ€ ν•¨μˆ˜μ˜ λ³€μˆ˜λ“€μ„ 계속 μ°Έμ‘°ν•  수 있게 됨. (κ°’ 변경도 κ°€λŠ₯)
μ™ΈλΆ€ ν•¨μˆ˜μ˜ μŠ€μ½”ν”„λ₯Ό μ°Έμ‘°ν•˜μ§€ μ•Šμ„ κ²½μš°μ—λŠ” λͺ¨λ˜ λΈŒλΌμš°μ €μ˜ μ΅œμ ν™” κΈ°λŠ₯에 μ˜ν•΄ ν΄λ‘œμ €λ‘œ νŒλ‹¨λ˜μ§€ μ•ŠμŒ. (λ©”λͺ¨λ¦¬ 효율 κ΅Ώ)


🧡 λ©”λͺ¨λ¦¬ 관리와 ν΄λ‘œμ €

μ™ΈλΆ€ ν•¨μˆ˜κ°€ μ’…λ£Œλ˜μ—ˆλ”λΌλ„, λ‚΄λΆ€ ν•¨μˆ˜κ°€ κ·Έ ν™˜κ²½μ„ μ°Έμ‘°ν•˜κ³  μžˆλ‹€λ©΄ κ·Έ λ ‰μ‹œμ»¬ ν™˜κ²½μ€ GC(Garbage Collection)의 λŒ€μƒμ΄ λ˜μ§€ μ•ŠμŒ.

즉, ν΄λ‘œμ €λŠ” λ©”λͺ¨λ¦¬λ₯Ό μ μœ ν•œ 채 μœ μ§€λ  수 있음
λͺ¨λ˜ μžλ°”μŠ€ν¬λ¦½νŠΈ μ—”μ§„(V8 λ“±)은 μ΅œμ ν™”λ₯Ό μˆ˜ν–‰ν•΄ μ‹€μ œλ‘œ μ‚¬μš©λ˜μ§€ μ•ŠλŠ” μƒμœ„ μŠ€μ½”ν”„μ˜ μ‹λ³„μžλŠ” κΈ°μ–΅ν•˜μ§€ μ•Šμ•„μ„œ λ©”λͺ¨λ¦¬ λ‚­λΉ„λ₯Ό 쀄일 수 있음.


πŸ“Œ ν΄λ‘œμ €κ°€ λ§Œλ“€μ–΄μ§€λŠ” 일반적인 쑰건

ν΄λ‘œμ €κ°€ μ„±λ¦½λ˜λ €λ©΄ μ•„λž˜ 두 쑰건이 μΆ©μ‘±λ˜μ–΄μ•Ό 함

  1. 쀑첩 ν•¨μˆ˜κ°€ μ™ΈλΆ€ ν•¨μˆ˜λ³΄λ‹€ 였래 μœ μ§€λ˜μ–΄μ•Ό 함
  2. 쀑첩 ν•¨μˆ˜κ°€ μƒμœ„ μŠ€μ½”ν”„μ˜ μ‹λ³„μž(자유 λ³€μˆ˜)λ₯Ό μ°Έμ‘°ν•΄μ•Ό 함

πŸ“š 자유 λ³€μˆ˜(Free Variable)λž€?

λ‚΄λΆ€ ν•¨μˆ˜κ°€ μ‚¬μš©ν•˜λŠ” λ³€μˆ˜ 쀑, μžμ‹ μ˜ μŠ€μ½”ν”„μ— μ‘΄μž¬ν•˜μ§€ μ•ŠλŠ” λ³€μˆ˜λ₯Ό 자유 λ³€μˆ˜λΌκ³  λΆ€λ₯Έλ‹€. ν΄λ‘œμ €λŠ” 이런 자유 λ³€μˆ˜λ“€μ„ μžμ‹ μ΄ 선언될 λ‹Ήμ‹œμ˜ λ ‰μ‹œμ»¬ ν™˜κ²½μ— μ €μž₯ν•˜μ—¬ 계속 μ‚¬μš©ν•  수 μžˆλ„λ‘ ν•΄μ£ΌλŠ” 것

ν΄λ‘œμ €λΌλŠ” μ΄λ¦„μ˜ 의미 λ˜ν•œ ν•¨μˆ˜κ°€ 자유 λ³€μˆ˜μ— μ˜ν•΄ λ‹«ν˜€μžˆλ‹€λŠ” 의미
자유 λ³€μˆ˜λ₯Ό μ‚¬μš©ν•  수 있게 ν•΄μ£ΌλŠ”λ° μ˜€ν”„λ„ˆ μ•„λ‹Œμ§€


πŸ›‘οΈ ν΄λ‘œμ €μ˜ ν™œμš© μ˜ˆμ‹œ: μƒνƒœ 은닉

ν΄λ‘œμ €λŠ” μƒνƒœλ₯Ό μ€λ‹‰ν•˜κ±°λ‚˜ νŠΉμ • ν•¨μˆ˜μ—μ„œλ§Œ μ ‘κ·Ό κ°€λŠ₯ν•˜κ²Œ λ§Œλ“€κ³  싢을 λ•Œ μœ μš©ν•¨

function counter() {
  let count = 0;

  return function() {
    count++;
    console.log(count);
  };
}

const myCounter = counter();
myCounter(); // 1
myCounter(); // 2

μ—¬κΈ°μ„œ countλŠ” μ™ΈλΆ€μ—μ„œ μ ‘κ·Όν•  수 μ—†κ³  myCounterλ₯Ό ν†΅ν•΄μ„œλ§Œ μ ‘κ·Ό κ°€λŠ₯ν•˜λ‹€.
이런 κ΅¬μ‘°λŠ” 정보 μ€λ‹‰μ΄λ‚˜ λͺ¨λ“ˆ νŒ¨ν„΄ κ΅¬ν˜„μ— 탁월함


πŸ“ ν΄λ‘œμ €μ™€ ν•¨μˆ˜ν˜• ν”„λ‘œκ·Έλž˜λ°

ν•¨μˆ˜ν˜• ν”„λ‘œκ·Έλž˜λ°μ—μ„œλŠ” λΆˆλ³€μ„±μ„ μ€‘μš”μ‹œν•œλ‹€.
μ™ΈλΆ€ μƒνƒœλ₯Ό λ³€κ²½ν•˜μ§€ μ•ŠλŠ” 것이 핡심인데, ν΄λ‘œμ €λ₯Ό 톡해 λΆ€μˆ˜ 효과(Side Effects)λ₯Ό 쀄일 수 μžˆλ‹€.

ν΄λ‘œμ €λ₯Ό μ΄μš©ν•˜λ©΄ μƒνƒœλ₯Ό ν•¨μˆ˜ λ‚΄λΆ€λ‘œ 숨길 수 μžˆμ–΄ 였λ₯˜ κ°€λŠ₯성이 쀄고 μœ μ§€λ³΄μˆ˜λ„ μ‰¬μ›Œμ Έ 자주 μ‚¬μš©λ˜λŠ” νŒ¨ν„΄μ΄λ‹€.


πŸ“ˆ ν΄λ‘œμ € μ‚¬μš© μ‹œ μ£Όμ˜ν•  점

  • λ©”λͺ¨λ¦¬ λˆ„μˆ˜: ν΄λ‘œμ €κ°€ λΆˆν•„μš”ν•˜κ²Œ μƒμœ„ ν™˜κ²½μ„ 였래 μ°Έμ‘°ν•˜λ©΄ λ©”λͺ¨λ¦¬κ°€ ν•΄μ œλ˜μ§€ μ•Šμ„ 수 있음. (λͺ¨λ˜ λΈŒλΌμš°μ € μ΅œμ ν™”μ— μ˜ν•΄ κ΄€λ¦¬λ˜κΈ° λ•Œλ¬Έμ— λ©”λͺ¨λ¦¬ λ‚­λΉ„ 및 λˆ„μˆ˜μ— λŒ€ν•΄ κ³ λ―Όν•˜μ§€ μ•Šμ•„λ„ λ˜μ§€λ§Œ 기본적으둜 ν΄λ‘œμ €λ₯Ό λŒ€ν•  λ•Œ μ•Œμ•„λ‘λ©΄ 쒋을 λ“― ν•˜λ‹€.)
  • 순수 ν•¨μˆ˜ μœ„λ°˜: ν΄λ‘œμ €λŠ” μƒνƒœλ₯Ό μœ μ§€ν•˜λ―€λ‘œ, ν•¨μˆ˜ν˜• ν”„λ‘œκ·Έλž˜λ° κ΄€μ μ—μ„œλŠ” μˆœμˆ˜ν•˜μ§€ μ•Šμ€ ν•¨μˆ˜λ‘œ 간주될 수 있음.

βœ… ν΄λ‘œμ € μš”μ•½

ν•­λͺ©μ„€λͺ…
μ •μ˜ν•¨μˆ˜μ™€ ν•¨μˆ˜κ°€ μ„ μ–Έλœ λ ‰μ‹œμ»¬ ν™˜κ²½μ˜ μ‘°ν•©
λͺ©μ μ™ΈλΆ€ ν•¨μˆ˜ λ³€μˆ˜ μ°Έμ‘°, μƒνƒœ μœ μ§€
쑰건쀑첩 ν•¨μˆ˜κ°€ μ™ΈλΆ€ ν•¨μˆ˜λ³΄λ‹€ 였래 생쑴 & 자유 λ³€μˆ˜ μ°Έμ‘°
ν™œμš©μƒνƒœ 은닉, μΊ‘μŠν™”, λͺ¨λ“ˆ νŒ¨ν„΄ λ“±
μœ μ˜μ‚¬ν•­λ©”λͺ¨λ¦¬ λˆ„μˆ˜ κ°€λŠ₯μ„±, κ³Όλ„ν•œ μ°Έμ‘° μ§€μ–‘

πŸ™‹β€β™‚οΈ ν΄λ‘œμ € ν™œμš© 질문

ν΄λ‘œμ €λŠ” μ–Έμ œ λ§Œλ“€μ–΄μ§€λ‚˜
ν•¨μˆ˜κ°€ μ •μ˜λ  λ•Œ ν΄λ‘œμ €κ°€ λ§Œλ“€μ–΄μ§.
μ‹€ν–‰ μ‹œμ μ΄ μ•„λ‹ˆλΌ μ„ μ–Έ μ‹œμ μ΄λΌλŠ” 게 μ€‘μš”ν•˜λ‹€.

ν΄λ‘œμ €λŠ” λ©”λͺ¨λ¦¬μ— μ–Όλ§ˆλ‚˜ 였래 λ‚¨λ‚˜
μ°Έμ‘°κ°€ κ³„μ†λ˜λŠ” ν•œ GC에 μ˜ν•΄ ν•΄μ œλ˜μ§€ μ•Šκ³  μœ μ§€λ¨.

λͺ¨λ“  쀑첩 ν•¨μˆ˜κ°€ ν΄λ‘œμ €μΈμ§€
μ•„λ‹ˆλ‹€. μƒμœ„ μŠ€μ½”ν”„μ˜ λ³€μˆ˜λ₯Ό μ°Έμ‘°ν•˜μ§€ μ•ŠλŠ”λ‹€λ©΄ ν΄λ‘œμ €κ°€ μ•„λ‹ˆλ‹€.

ν΄λ‘œμ €λŠ” μ™œ λ©”λͺ¨λ¦¬ λˆ„μˆ˜λ‚˜ λ‚­λΉ„λ₯Ό μœ λ°œν•˜λŠ”μ§€
μ‚¬μš©ν•˜μ§€ μ•ŠλŠ” λ ‰μ‹œμ»¬ ν™˜κ²½λ„ 계속 μœ μ§€λ˜κΈ° λ•Œλ¬Έ
λͺ¨λ˜ λΈŒλΌμš°μ €μ˜ μ΅œμ ν™”λ₯Ό 톡해 ν•΄κ²° κ°€λŠ₯ν•˜μ§€λ§Œ, λ‹€λ₯Έ ν™˜κ²½μ΄λ‚˜ κ΅¬ν˜• λΈŒλΌμš°μ €μ—μ„œ ν΄λ‘œμ €λ₯Ό μ‚¬μš©ν•΄μ•Όν•œλ‹€λ©΄ μœ μ˜ν•΄μ•Όν•  뢀뢄이닀.

ν΄λ‘œμ €λ₯Ό ν™œμš©ν•œ 싀무 예제

  • Vue, React의 setup ν•¨μˆ˜ λ‚΄λΆ€ μƒνƒœ
  • JavaScript λͺ¨λ“ˆ κ΅¬ν˜„
  • private λ³€μˆ˜ κ΅¬ν˜„ λ“±

JSμ—μ„œ ν΄λ‘œμ € 없이 λΉ„μŠ·ν•œ κΈ°λŠ₯을 κ΅¬ν˜„ν•  수 μžˆλŠ”μ§€
ES6의 ν΄λž˜μŠ€λ‚˜ Symbol 등을 톡해 μœ μ‚¬ν•œ ꡬ쑰λ₯Ό κ΅¬ν˜„ν•  μˆ˜λŠ” μžˆμ§€λ§Œ, ν΄λ‘œμ €λ§ŒνΌ μ§κ΄€μ μ΄κ±°λ‚˜ λͺ…μ‹œμ μ΄μ§€ μ•ŠμŒ.


✍️ 마무리

ν΄λ‘œμ €λŠ” μžλ°”μŠ€ν¬λ¦½νŠΈμ—μ„œ κ°€μž₯ κ°•λ ₯ν•˜λ©΄μ„œλ„ μ˜€ν•΄λ°›κΈ° μ‰¬μš΄ κ°œλ…μ΄λ‹€.
μ œλŒ€λ‘œ μ΄ν•΄ν•˜κ³  λ‚˜λ©΄ μƒνƒœ 관리, 정보 은닉, λͺ¨λ“ˆν™” λ“± μ—¬λŸ¬ μƒν™©μ—μ„œ μ•„μ£Ό μœ μš©ν•˜κ²Œ ν™œμš© κ°€λŠ₯ν•˜λ‹€.


πŸ”— μ°Έκ³  링크

profile
Hello World !

0개의 λŒ“κΈ€