[🐱 μžλ°”μŠ€ν¬λ¦½νŠΈ] Closure(ν΄λ‘œμ €)

dsfasdΒ·2022λ…„ 9μ›” 8일
0

μžλ°”μŠ€ν¬λ¦½νŠΈ

λͺ©λ‘ 보기
2/4

μžλ°”μŠ€ν¬λ¦½νŠΈ Closure


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

ν•¨μˆ˜μ™€ λ ‰μ‹œμ»¬ ν™˜κ²½μ˜ μ‘°ν•©

ν•¨μˆ˜κ°€ 생성될 λ‹Ήμ‹œμ˜ μ™ΈλΆ€ λ³€μˆ˜λ₯Ό κΈ°μ–΅

생성 이후에도 계속 μ ‘κ·Ό κ°€λŠ₯

ν΄λ‘œμ € λŠ” ν•¨μˆ˜λ₯Ό μ€‘μ²©μœΌλ‘œ μ‚¬μš©ν•¨μœΌλ‘œμ¨ λ³€μˆ˜μ˜ λ ‰μ‹œμ»¬ ν™˜κ²½(μ–΄νœ˜μ  λ²”μœ„)을 μ§€μ •ν•΄μ£ΌλŠ” 것을 μ˜λ―Έν•œλ‹€. μ—¬κΈ°μ„œ "lexical"μ΄λž€, μ–΄νœ˜μ  λ²”μœ„ 지정(lexical scoping) κ³Όμ •μ—μ„œ λ³€μˆ˜κ°€ μ–΄λ””μ—μ„œ μ‚¬μš© κ°€λŠ₯ν•œμ§€ μ•ŒκΈ° μœ„ν•΄ κ·Έ λ³€μˆ˜κ°€ μ†ŒμŠ€μ½”λ“œ λ‚΄ μ–΄λ””μ—μ„œ μ„ μ–Έλ˜μ—ˆλŠ”μ§€ κ³ λ €ν•œλ‹€λŠ” 것을 μ˜λ―Έν•œλ‹€.


🍎 Lexical Environment (λ ‰μ‹œμ»¬ ν™˜κ²½, μ–΄νœ˜μ  ν™˜κ²½) :

ν•¨μˆ˜ μ„ μ–ΈμœΌλ‘œ 인해 μŠ€μ½”ν”„κ°€ λ°œμƒν•˜κ²Œ 되고, 각각 μƒμ„±λœ μŠ€μ½”ν”„μ— λ”°λΌμ„œ λ‹€λ₯Έ λ ‰μ‹œμ»¬ ν™˜κ²½(Lexical Environment)을 κ°–λŠ”λ‹€.

λ ‰μ‹œμ»¬ ν™˜κ²½μ„ 크게 λΆ„λ₯˜ν•΄λ³΄λ©΄ λ‹€μŒκ³Ό κ°™λ‹€.

μ „μ—­ Lexical ν™˜κ²½ > μ™ΈλΆ€ ν•¨μˆ˜ Lexical ν™˜κ²½ > λ‚΄λΆ€ ν•¨μˆ˜(읡λͺ…ν•¨μˆ˜) Lexical ν™˜κ²½

λ‹€μŒμ˜ mdn 예제λ₯Ό μ‚΄νŽ΄λ³΄μž.

   function init() {
     var name = "Mozilla"; // name은 init에 μ˜ν•΄ μƒμ„±λœ 지역 λ³€μˆ˜μ΄λ‹€.
     function displayName() { // displayName() 은 λ‚΄λΆ€ ν•¨μˆ˜μ΄λ©°, ν΄λ‘œμ €λ‹€.
       alert(name); // λΆ€λͺ¨ ν•¨μˆ˜μ—μ„œ μ„ μ–Έλœ λ³€μˆ˜λ₯Ό μ‚¬μš©ν•œλ‹€.
     }
     displayName();
   }
   init();

μœ„ μ˜ˆμ œλŠ” init ν•¨μˆ˜μ™€ κ·Έ λ‚΄λΆ€μ˜ ν•¨μˆ˜ displayName ν•¨μˆ˜κ°€ μ€‘μ²©λœ ꡬ쑰이닀. 이 λ•Œ init ν•¨μˆ˜λŠ” displayName ν•¨μˆ˜λ₯Ό ν’ˆμ€ μ™ΈλΆ€ ν•¨μˆ˜μ— ν•΄λ‹Ήν•˜κ³ , displayName ν•¨μˆ˜λŠ” λ‚΄λΆ€ ν•¨μˆ˜μ— ν•΄λ‹Ήν•œλ‹€.

κ·Έλ ‡λ‹€λ©΄ 이제 λ ‰μ‹œμ»¬ ν™˜κ²½μ„ νŒŒμ•…ν•  수 μžˆλ‹€. init ν•¨μˆ˜μ˜ μ½”λ“œλΈ”λŸ­ λ²”μœ„λŠ” μ™ΈλΆ€ lexical ν™˜κ²½μ΄λ‹€. init ν•¨μˆ˜ 내뢀에 μ„ μ–Έλœ var name = "Mozilla"λŠ” μ™ΈλΆ€ λ ‰μ‹œμ»¬ ν™˜κ²½μ— μ„ μ–Έλœ λ³€μˆ˜μž„μ„ μ•Œ 수 μžˆλ‹€. λ§ˆμ°¬κ°€μ§€λ‘œ displayName ν•¨μˆ˜ λ‚΄λΆ€μ˜ μ½”λ“œ λΈ”λŸ­ λ²”μœ„λŠ” λ‚΄λΆ€ lexical ν™˜κ²½ λ²”μœ„λΌκ³  λ³Ό 수 μžˆλ‹€.

μœ„ ν΄λ‘œμ €μ˜ μ„€λͺ…μ—μ„œ ν•¨μˆ˜μ™€ λ ‰μ‹œμ»¬ ν™˜κ²½μ˜ 쑰합이라고 ν•œ μ΄μœ λ„ 이와 κ°™λ‹€. ν•¨μˆ˜λ₯Ό 생성함과 λ™μ‹œμ— λ ‰μ‹œμ»¬ ν™˜κ²½μ΄ μ •μ˜λœλ‹€. ν΄λ‘œμ €λŠ” λ ‰μ‹œμ»¬ ν™˜κ²½μ˜ κ°œλ…μ„ μ΄μš©ν•˜μ—¬ μ™„μ„±ν•œ κ°œλ…μ΄κΈ° λ•Œλ¬Έμ΄λ‹€.


🍎 ν΄λ‘œμ € 예제

ν΄λ‘œμ €λŠ” κ°œλ…μ„ μ„€λͺ…ν•˜λŠ” 것보닀 예제둜 μ΄ν•΄ν•˜λŠ” 것이 더 μ΄ν•΄ν•˜κΈ° 쉽닀.
λ§ˆμ°¬κ°€μ§€λ‘œ mdn의 예제λ₯Ό μ‚΄νŽ΄λ³΄μž

function makeFunc() {
      var name = "Mozilla";
      function displayName() {
        alert(name);
      }
      return displayName;
    }

var myFunc = makeFunc();
    //myFuncλ³€μˆ˜μ— displayName을 리턴함
    //μœ νš¨λ²”μœ„μ˜ μ–΄νœ˜μ  ν™˜κ²½μ„ μœ μ§€
myFunc();
    //λ¦¬ν„΄λœ displayName ν•¨μˆ˜λ₯Ό μ‹€ν–‰(name λ³€μˆ˜μ— μ ‘κ·Ό)
	//"Mozilla" 창이 λ„μ›Œμ§„λ‹€.  

μœ„μ˜ λ ‰μ‹œμ»¬ ν™˜κ²½μ—μ„œ μ‚¬μš©λœ μ˜ˆμ œμ™€ λΉ„μŠ·ν•˜λ‹€. μƒˆλ‘œ μΆ”κ°€λœ myFunc λ³€μˆ˜μ— μ£Όλͺ©ν•˜μž. myFunc λ³€μˆ˜μ—λŠ” makeFunc ν•¨μˆ˜λ₯Ό μ‹€ν–‰ν•œ 리턴값, 즉 ν•¨μˆ˜λ₯Ό λ‹΄κ³ μžˆλ‹€. displayName ν•¨μˆ˜λŠ” λ‚΄λΆ€ μŠ€μ½”ν”„μ΄λ―€λ‘œ μ™ΈλΆ€ μŠ€μ½”ν”„μ˜ name = "Mozilla" 값을 μ°Έμ‘°ν•  수 μžˆλ‹€.

μ—¬κΈ°μ„œ ν΄λ‘œμ €μ˜ κ°œλ…μ΄ λͺ…확해진닀. 맨 μ•„λž˜ 쀄에 myFunc( )λ₯Ό ν˜ΈμΆœν•˜λ©΄ Mozillaκ°€ 창에 λœ¨λŠ” 것을 확인할 수 μžˆλ‹€. ν΄λ‘œμ €λŠ” ν•¨μˆ˜κ°€ 생성될 λ‹Ήμ‹œμ˜ μ™ΈλΆ€ λ³€μˆ˜λ₯Ό κΈ°μ–΅ν•œλ‹€κ³  ν–ˆκ³ , 생성 이후에도 계속 μ ‘κ·Ό κ°€λŠ₯ν•˜λ‹€κ³  ν–ˆλ‹€.

μ¦‰μ‹œμ‹€ν–‰ν•¨μˆ˜κ°€ λ°˜ν™˜ν•œ ν•¨μˆ˜λŠ” μžμ‹ μ΄ 생성됐을 λ•Œμ˜ λ ‰μ‹œμ»¬ ν™˜κ²½(Lexical environment)에 μ†ν•œ λ³€μˆ˜ myFunc λ₯Ό κΈ°μ–΅ν•˜λŠ” ν΄λ‘œμ €λ‹€.

즉, myFunc에 μ €μž₯ν•œ displayName의 리턴값은 μ™ΈλΆ€ ν•¨μˆ˜ makeFunc에 μ €μž₯된 name = "Mozilla"값을 μ €μž₯ν•˜κ³  μ‚¬μš©ν•˜λŠ” 것이닀.
μ΄λŠ” displayName ν•¨μˆ˜κ°€ ν΄λ‘œμ €λ₯Ό ν˜•μ„±ν•˜μ—¬ κ°€λŠ₯ν•œ 일이닀.
일반적인 ν•¨μˆ˜μ˜ 경우 ν•¨μˆ˜ μ’…λ£Œ μ‹œ ν•¨μˆ˜ λ‚΄λΆ€ λ³€μˆ˜μ— 더 이상 μ ‘κ·Όν•  수 μ—†κ²Œ λœλ‹€.


🍎 ν΄λ‘œμ €λ₯Ό μ‚¬μš©ν•˜λ©΄ 쒋은 경우

κ·Έλ ‡λ‹€λ©΄ μ–΄λ–€ κ²½μš°μ— ν΄λ‘œμ €λ₯Ό μ‚¬μš©ν•˜λ©΄ μ’‹μ„κΉŒ?

μƒνƒœ μœ μ§€

ν΄λ‘œμ €κ°€ κ°€μž₯ μœ μš©ν•˜κ²Œ μ‚¬μš©λ˜λŠ” 상황은 ν˜„μž¬ μƒνƒœλ₯Ό κΈ°μ–΅ν•˜κ³  λ³€κ²½λœ μ΅œμ‹  μƒνƒœλ₯Ό μœ μ§€ν•˜λŠ” 것이닀.

λ§Œμ•½ μžλ°”μŠ€ν¬λ¦½νŠΈμ— ν΄λ‘œμ €λΌλŠ” κΈ°λŠ₯이 μ—†λ‹€λ©΄ μƒνƒœλ₯Ό μœ μ§€ν•˜κΈ° μœ„ν•΄ μ „μ—­ λ³€μˆ˜λ₯Ό μ‚¬μš©ν•  수 밖에 μ—†λ‹€. μ „μ—­ λ³€μˆ˜λŠ” μ–Έμ œλ“ μ§€ λˆ„κ΅¬λ‚˜ μ ‘κ·Όν•  수 있고 λ³€κ²½ν•  수 있기 λ•Œλ¬Έμ— λ§Žμ€ λΆ€μž‘μš©μ„ μœ λ°œν•΄ 였λ₯˜μ˜ 원인이 λ˜λ―€λ‘œ μ‚¬μš©μ„ μ–΅μ œν•΄μ•Ό ν•œλ‹€.

μ „μ—­ λ³€μˆ˜μ˜ μ‚¬μš© μ–΅μ œ

μ „μ—­ λ³€μˆ˜λŠ” μ–Έμ œλ“ μ§€ λˆ„κ΅¬λ‚˜ μ ‘κ·Όν•  수 있고 λ³€κ²½ν•  수 μžˆλ‹€. μ΄λŠ” μ˜λ„μΉ˜ μ•Šκ²Œ 값이 변경될 수 μžˆλ‹€λŠ” 것을 μ˜λ―Έν•œλ‹€. λ§Œμ•½ λˆ„κ΅°κ°€μ— μ˜ν•΄ μ˜λ„μΉ˜ μ•Šκ²Œ μ „μ—­ λ³€μˆ˜μ˜ 값이 변경됐닀면 μ΄λŠ” 였λ₯˜λ‘œ 이어진닀.

좜처: https://poiemaweb.com/js-closure


🍎 ν΄λ‘œμ €μ˜ μž₯점

ν΄λ‘œμ €λ₯Ό 톡해 ν•¨μˆ˜ 내뢀에 λ¦¬ν„΄λœ 값을 λ³€μˆ˜μ— μ €μž₯ν•˜λ©΄ μ™ΈλΆ€ ν•¨μˆ˜μ˜ λ³€μˆ˜λ₯Ό 계속 μ‚¬μš©ν•  수 μžˆμ—ˆλ‹€. μ΄λŠ” 이제 μ–΄λ– ν•œ λ°©μ‹μœΌλ‘œλ„ μ™ΈλΆ€ μŠ€μ½”ν”„μ—μ„œλŠ” λ³€μˆ˜μ˜ 직접적인 μ°Έμ‘°κ°€ λΆˆκ°€λŠ₯ν•˜λ‹€λŠ” μ˜λ―Έμ΄κΈ°λ„ ν•˜λ‹€.

μ΄λŸ¬ν•œ κ³Όμ •μ—μ„œ μ˜€λŠ” ν΄λ‘œμ €μ˜ μž₯점은 λ‹€μŒκ³Ό κ°™λ‹€.

μΊ‘μŠν™” (μ •λ³΄μ˜ μ ‘κ·Ό μ œν•œ)

  • μ†ŒμŠ€μ½”λ“œλ₯Ό μž‘μ„±ν•˜λŠ” κ³Όμ •μ—μ„œ λ³€μˆ˜μ˜ 직접적인 접근을 μ™„μ „νžˆ μ°¨λ‹¨ν•¨μœΌλ‘œμ¨ side effect(μ˜λ„λ˜μ§€ μ•Šμ€ λ³€κ²½)λ₯Ό μ΅œμ†Œν™” ν•œλ‹€.

ν•¨μˆ˜ λͺ¨λ“ˆν™”에 유리

  • λͺ¨λ“ˆν™” : ν•¨μˆ˜ ν•˜λ‚˜λ₯Ό μ™„μ „νžˆ 독립적인 λΆ€ν’ˆ ν˜•νƒœλ‘œ λΆ„λ¦¬ν•˜λŠ” 것.
  • ν΄λ‘œμ €λ₯Ό 톡해 데이터와 λ©”μ„œλ“œλ₯Ό 묢으면 ν•¨μˆ˜ μž¬μ‚¬μš©μ„±μ΄ κ·ΉλŒ€ν™” λ˜μ–΄ λͺ¨λ“ˆν™”에 μœ λ¦¬ν•˜λ‹€.
profile
기둝을 μ •λ¦¬ν•˜λŠ” 곡간!

0개의 λŒ“κΈ€