λ³Έλ¬Έ λ°”λ‘œκ°€κΈ°
πŸ“‹Technical interview(Front)

Closure ν΄λ‘œμ €

by λ…Ήμ°¨λ§›κ°œκ΅¬λ¦¬ 2022. 10. 23.

πŸ’‘ν΄λ‘œμ €λž€

ν΄λ‘œμ €λŠ” μ£Όλ³€μ˜ μƒνƒœ (lexical environment)의 참쑰와 ν•¨κ»˜ λ²ˆλ“€λ‘œ 묢인 ν•¨μˆ˜μ˜ μ‘°ν•©μž…λ‹ˆλ‹€. 즉, ν΄λ‘œμ ΈλŠ” μš°λ¦¬μ—κ²Œ innerν•¨μˆ˜μ—μ„œ outerν•¨μˆ˜μ˜ μŠ€μ½”ν”„μ— 접근을 κ°€λŠ₯ν•˜κ²Œ ν•΄μ€λ‹ˆλ‹€. μžλ°”μŠ€ν¬λ¦½νŠΈμ—μ„œ ν΄λ‘œμ €λŠ” ν•¨μˆ˜κ°€ 생성될 λ•Œλ§ˆλ‹€ μƒμ„±λ©λ‹ˆλ‹€.

μ•„λž˜λŠ” ν΄λ‘œμ €λ₯Ό μ„€λͺ…ν•˜λŠ” μ—¬λŸ¬ λ¬Έμ„œμ—μ„œ μ°Έκ³ ν•œ 것이닀.

 

ν•¨μˆ˜μ™€ ν•¨μˆ˜κ°€ μ„ μ–Έλœ μ–΄νœ˜μ (lexical) ν™˜κ²½μ˜ μ‘°ν•©

  • ν΄λ‘œμ €λŠ” ν•¨μˆ˜λ₯Ό μ§€μΉ­ν•˜κ³  또 κ·Έ ν•¨μˆ˜κ°€ μ„ μ–Έλœ ν™˜κ²½κ³Όμ˜ κ΄€κ³„λΌλŠ” κ°œλ…μ΄ 합쳐진것이닀.

ν΄λ‘œμ €μ˜ 핡심은 μŠ€μ½”ν”„λ₯Ό μ΄μš©ν•΄μ„œ, λ³€μˆ˜μ˜ μ ‘κ·Ό λ²”μœ„λ₯Ό λ‹«λŠ”(폐쇄)것에 μžˆλ‹€.

  • μ™ΈλΆ€ν•¨μˆ˜ μŠ€μ½”ν”„μ—μ„œ λ‚΄λΆ€ν•¨μˆ˜ μŠ€μ½”ν”„λ‘œ μ ‘κ·Ό λΆˆκ°€λŠ₯ν•˜λ‹€.
  • λ‚΄λΆ€ν•¨μˆ˜μ—μ„œλŠ” μ™ΈλΆ€ν•¨μˆ˜ μŠ€μ½”ν”„μ—μ„œ μ„ μ–Έλœ λ³€μˆ˜μ— μ ‘κ·Ό κΈ°λŠ₯ν•˜λ‹€.
  • λ”°λΌμ„œ λ‚΄λΆ€ ν•¨μˆ˜λŠ” μ™ΈλΆ€ν•¨μˆ˜μ— μ„ μ–Έλœ λ³€μˆ˜μ— μ ‘κ·Ό κ°€λŠ₯ν•˜λ‹€.

ν•¨μˆ˜κ°€ ν˜ΈμΆœλ˜λŠ” ν™˜κ²½κ³Ό λ³„κ°œλ‘œ, 기쑴에 μ„ μ–Έλ˜μ–΄ 있던 ν™˜κ²½(μ–΄νœ˜μ  ν™˜κ²½)을 κΈ°μ€€μœΌλ‘œ λ³€μˆ˜λ₯Ό μ‘°νšŒν•œλ‹€.

  • μ™ΈλΆ€ν•¨μˆ˜μ˜ 싀행이 μ’…λ£Œλœ 후에도, ν΄λ‘œμ € ν•¨μˆ˜λŠ” μ™ΈλΆ€ν•¨μˆ˜μ˜ μŠ€μ½”ν”„, 즉, ν•¨μˆ˜κ°€ μ„ μ–Έλœ μ–΄νœ˜μ  ν™˜κ²½μ— μ ‘κ·Όν•  수 μžˆμŠ΅λ‹ˆλ‹€.
  • μ™ΈλΆ€ ν•¨μˆ˜ μŠ€μ½”ν”„κ°€ λ‚΄λΆ€ν•¨μˆ˜μ— μ˜ν•΄ μ–Έμ œλ“ μ§€ 참쑰될 수 μžˆλ‹€.
  • λ”°λΌμ„œ ν΄λ‘œμ €λ₯Ό λ‚¨λ°œν•  경우 퍼포먼슀 μ €ν•˜κ°€ λ°œμƒν•  μˆ˜λ„ μžˆμŠ΅λ‹ˆλ‹€.

μƒμœ„ μŠ€μ½”ν”„μ˜ μ‹λ³„μžλ₯Ό ν¬ν•¨ν•˜μ—¬ μ“°μ—¬μžˆλŠ” λ‚΄λΆ€ ν•¨μˆ˜ μ½”λ“œ 자체λ₯Ό μ–΄νœ˜μ  ν™˜κ²½(lexical environment)라고 λΆ€λ₯Ό 수 μžˆλ‹€.

 

 

🐸 : 사싀 처음 읽어보면 ν•˜λ‚˜λ„ 이해가 μ•ˆλ κΊΌμ—μš”, 저도 κ·Έλž¬μŠ΅λ‹ˆλ‹€,,, κ²Œλ‹€κ°€ execution context에 λŒ€ν•œ
사전 지식이 μ—†μœΌλ©΄ 더 νž˜λ“€κΊΌμ—μš” ν•˜μ§€λ§Œ 천천히 읽어내렀가보면 감은 μž‘μœΌμ‹€ 수 μžˆμ„κ±°μ—μš”

ν΄λ‘œμ € μ˜ˆμ‹œ

ν”νžˆ ν•¨μˆ˜( outer() ) λ‚΄μ—μ„œ ν•¨μˆ˜λ₯Ό μ •μ˜( inner() )ν•˜κ³  μ‚¬μš©ν•˜λ©΄ ν΄λ‘œμ €λΌκ³  ν•œλ‹€.

ν•˜μ§€λ§Œ λŒ€κ°œλŠ” μ •μ˜ν•œ ν•¨μˆ˜λ₯Ό λ¦¬ν„΄ν•˜κ³  μ‚¬μš©μ€ λ°”κΉ₯μ—μ„œ ν•˜κ²Œλœλ‹€.

μ˜ˆμ‹œλ₯Ό 보며 λ‹¨κ³„λ³„λ‘œ μ΄ν•΄ν•΄κ°€μž.

 

μ•„λž˜ μ½”λ“œλ₯Ό 보면

<script>
  let n0 = 'n0';
  function fn1() {
    let n2 = 'n2';
    console.log(n0, n1, n2)
  }

  function fn2() {
    let n1 = 'n1';
    console.log(n0, n1)
    fn1();
  }
  fn2();
</script>

fn2 ν•¨μˆ˜μ•ˆμ—μ„œ fn1 ν•¨μˆ˜λ₯Ό ν˜ΈμΆœν–ˆλ‹€ ν•˜λ”λΌλ„

fn1μ—μ„œλŠ” fn2ν•¨μˆ˜μ•ˆμ— μžˆλŠ” n1λ³€μˆ˜μ— μ ‘κ·Όν•  수 μ—†λ‹€.

 

κ·Έ μ΄μœ λŠ” μžλ°”μŠ€ν¬λ¦½νŠΈκ°€ 정적 μŠ€μ½”ν”„λ₯Ό λ”°λ₯΄κΈ° λ•Œλ¬Έμ΄λ‹€.

❗❗Point
λ§Œμ•½ μ–΄λ””μ—μ„œ ν˜ΈμΆœν–ˆλŠλƒμ— λ”°λΌμ„œ μ ‘κ·Ό λ²”μœ„κ°€ 달라진닀면 그것을
동적 μŠ€μ½”ν”„ 라고 ν•œλ‹€(Dynamic scope)

μžλ°”μŠ€ν¬λ¦½νŠΈλŠ” ν•¨μˆ˜λ₯Ό μ–΄λ””μ„œ μ„ μ–Έν•˜μ˜€λŠ”지에 따라 μƒμœ„ μŠ€μ½”ν”„λ₯Ό κ²°μ •ν•˜λŠ”
정적 μŠ€μ½”ν”„μ΄λ‹€(Lexical scope or Static scope)

μžλ°”μŠ€ν¬λ¦½νŠΈλ₯Ό λΉ„λ‘―ν•œ λŒ€λΆ€λΆ„μ˜ ν”„λ‘œκ·Έλž˜λ° μ–Έμ–΄λŠ” λ ‰μ‹œμ»¬ μŠ€μ½”ν”„
🐸 : 처음 동적 μŠ€μ½”ν”„μ™€ 정적 μŠ€μ½”ν”„μ˜ μ •μ˜λ₯Ό λ“€μ—ˆμ„λ•Œ 이해가 μ•ˆκ°”κΈ° λ•Œλ¬Έμ— 저같은 μ‚¬λžŒμ΄ 있으리라 μƒκ°ν•˜κ³ 
       μ‘°κ·Έλ§ˆν•œ μ˜ˆμ‹œλ₯Ό 톡해 μ•„λž˜μ—μ„œ 쑰금 더 μžμ„Ένžˆ? μ„€λͺ… ν•΄λ“œλ¦¬κ² μλ‹ˆλ‹€!! 

πŸ‘‰πŸ»μΆ”κ°€μ„€λͺ…

πŸ”μ •μ  μŠ€μ½”ν”„

var n1 = 1;
function foo() {
   var n1 = 10;
   bar();
}

function bar() {
   console.log(n1);
}

foo();

 

μœ„μ—μ„œ ν•¨μˆ˜μ˜ μŠ€μ½”ν”„λ₯Ό κ²°μ •ν•˜λŠ” 방식이 ν˜ΈμΆœμ‹œμ μ΄ μ•„λ‹Œ μ„ μ–Έμ‹œμ μ΄λΌκ³  ν–ˆλŠ”λ°

 

λˆ„κ΅°κ°€λŠ” foo()ν•¨μˆ˜ μ•ˆμ— μžˆλŠ” n1 λ³€μˆ˜κ°€ 10이고 bar()ν•¨μˆ˜μ˜ console.log(x)κ°€

foo()ν•¨μˆ˜μ•ˆμ—μ„œ μ‹€ν–‰λ˜λ©΄μ„œ 10이 좜λ ₯λ˜λŠ” 것이 μ•„λ‹Œκ°€ ν•˜κ³  ν—·κ°ˆλ¦¬κΈ° 쉽닀.

 

ν•˜μ§€λ§Œ λ‹€μ‹œν•œλ²ˆ λ§κ·ΈλŒ€λ‘œ ν•¨μˆ˜μ˜ μ„ μ–Έμ‹œμ μ— μŠ€μ½”ν”„λ₯Ό κ²°μ •ν•œλ‹€κ³  ν–ˆμœΌλ‹ˆ,

barν•¨μˆ˜λ₯Ό 아직 μ–΄λ””μ„ κ°€ bar() ( =μ΄λŸ°μ‹μœΌλ‘œ) ν˜ΈμΆœν•˜κΈ° μ „μ˜ μž‘μ„±λ§Œ(=μ„ μ–Έ)ν•œ μ‹œμ μœΌλ‘œ λŒμ•„κ°€λ³΄λ©΄

bar ν•¨μˆ˜ μ‹œμ μ—μ„œλŠ” barν•¨μˆ˜μ•ˆμ˜ 둜컬 λ³€μˆ˜λ‘œxλŠ” μ—†μœΌλ‹ˆ μ „μ—­λ³€μˆ˜μΈ κ°€μž₯ μœ—μ€„μ˜ var n1 = 1 을 μ°Έκ³ ν•˜μ—¬

1이 κ²°κ³Όκ°’μœΌλ‘œ 좜λ ₯되게 λœλ‹€.

 

πŸ”λ™μ  μŠ€μ½”ν”„

μœ„μ˜ μ˜ˆμ‹œλ₯Ό 보면 동적 μŠ€μ½”ν”„μ— 해석을 λŒ€μž…μ‹œν‚€λŠ” 것은 어렡지 μ•Šμ„ 것이닀.

μ–΄λ””μ—μ„œ ν˜ΈμΆœν–ˆλŠλƒμ— λ”°λΌμ„œ μ ‘κ·Ό λ²”μœ„κ°€ 달라진닀면 그것을 동적 μŠ€μ½”ν”„ 라고 ν–ˆμœΌλ‹ˆ

 

λ§Œμ•½ μžλ°”μŠ€ν¬λ¦½νŠΈκ°€ 동적 μŠ€μ½”ν”„λ₯Ό μ‚¬μš©ν•œλ‹€λ©΄, 호좜 μœ„μΉ˜μ— 따라 λ²”μœ„κ°€ μ§€μ •λ˜λ‹ˆ

foo()ν•¨μˆ˜ μ•ˆμ—μ„œ 호좜된 4λ²ˆμ§Έμ€„μ— bar()λŠ” foo() ν•¨μˆ˜ 내뢀에 var n1 = 10으 영ν–₯을 λ°›μ•„

1이 μ•„λ‹Œ 10이 κ²°κ³Όκ°’μœΌλ‘œ λ‚˜μ™”μ„ 것이닀.

 


πŸ‘ˆπŸ»λ‹€μ‹œ λŒμ•„μ™€μ„œ

μ•„λž˜λŠ” ν΄λ‘œμ € ν•¨μˆ˜μ˜ μ˜ˆμ‹œμ΄λ‹€.

let n0 = 'n0';
function fn1() {
  function fn2() {
    let n2 = 'n2';
    console.log(n0, n1, n2);
  }
  let n1 = 'n1';
  console.log(n0, n1)
  fn2();
}

fn1();

μ΄λ ‡κ²Œ μœ„μ™€ 같이 ν•¨μˆ˜λ₯Ό ν•¨μˆ˜μ•ˆμ— μ •μ˜ν•˜λ©΄ κ·Έν•¨μˆ˜μ˜ λΆ€λͺ¨ν•¨μˆ˜μ˜ μŠ€μ½”ν”„μ— μ ‘κ·Όν•  수 μžˆλ‹€λΌλŠ” 것을

보여쀀닀.

 

ν•œλ²ˆλ” μ •λ¦¬ν•΄μ„œ
λ§ν•˜μžλ©΄ ν΄λ‘œμ €λž€ λ‚΄λΆ€ ν•¨μˆ˜κ°€ μ •μ˜λ  λ–„ μ™ΈλΆ€ ν•¨μˆ˜μ˜ ν™˜κ²½μ„ κΈ°μ–΅ν•˜κ³  μžˆλŠ” λ‚΄λΆ€ ν•¨μˆ˜λ₯Ό λ§ν•œλ‹€.

 

μ™ΈλΆ€ ν•¨μˆ˜ μ•ˆμ—μ„œ μ„ μ–Έλœ λ‚΄λΆ€ ν•¨μˆ˜λŠ” κ·Έ μ™ΈλΆ€ ν•¨μˆ˜μ˜ 지역 λ³€μˆ˜λ‚˜

ν•¨μˆ˜μ— μ ‘κ·Όν•˜μ—¬ μ‚¬μš©ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

 

❗❗Point

ν΄λ‘œμ € = νμ‡„ν•˜λ‹€,λ™λ΄‰ν•˜λ‹€

ν•¨μˆ˜κ°€λ§Œλ“€μ–΄μ§€λŠ” μ‹œμ μ—μ„œ λΆ€λͺ¨ν•¨μˆ˜κ°€ κ°€μ§€κ³ μžˆλŠ” μŠ€μ½”ν”„ μœ νš¨λ²”μœ„ λ³€μˆ˜λ“€μ„ λ™λ΄‰ν•΄μ„œ κ°€μ§€κ³ μžˆλ‹€λŠ” λœ»μ΄λ‹€.
μ–Έμ œλ“ μ§€ ν˜ΈμΆœν•˜λ©΄ λΆ€λͺ¨ν•¨μˆ˜μ˜ μŠ€μ½”ν”„ λ²”μœ„μ— μ ‘κ·Όν•  수 μžˆλ‹€.

 

 

크둬 개발자 도ꡬλ₯Ό 톡해 μ„ μ–Έλœ μŠ€μ½”ν”„λ₯Ό μ‚΄νŽ΄λ³΄λ©΄ Closure (fn1) μ•ˆμ— n1 : "n1"이 λ“€μ–΄μžˆλŠ” 것을 λ³Ό 수 μžˆλ‹€.

μ΄λ ‡κ²Œ ν•¨μˆ˜λ₯Ό ν•¨μˆ˜μ•ˆμ— μ •μ˜ν•˜λ©΄ κ·Έν•¨μˆ˜{ fn2() }의 λΆ€λͺ¨ν•¨μˆ˜μ˜{ fn1() } μ˜μŠ€μ½”ν”„μ— ν΄λ‘œμ € ν•¨μˆ˜λ₯Ό 톡해

μ ‘κ·Όν•  수 μžˆλ‹€λΌλŠ” 것을 μ•Œ 수 μžˆλ‹€.

 

μžλ°”μŠ€ν¬λ¦½νŠΈκ°€ μ•„λ‹Œ λ‹€λ₯Έ μ–Έμ–΄μ˜ κ²½ν—˜μœΌλ‘œ
outerμ‹€ν–‰λ˜λŠ” μˆœκ°„ λλ‚˜λ©΄ λ‚΄λΆ€μ˜ λ³€μˆ˜λ“€μ€ 사라진닀고 생각 ν•˜μ§€λ§Œ 값이 μ°νžŒλ‹€.
μƒμ„±ν•œ μ‹œμ μ˜ μŠ€μ½”ν”„ 체인을 계속 λ“€κ³  μžˆλŠ”λ‹€  = ν΄λ‘œμ €μ˜ νŠΉμ§•
πŸ“‹μ •λ¦¬
ν΄λ‘œμ €λž€ ν•¨μˆ˜μ™€ ν•΄λ‹Ή ν•¨μˆ˜κ°€ μ„ μ–Έλœ λ ‰μ‹œμ»¬ ν™˜κ²½μ˜ 쑰합이닀. μ™ΈλΆ€ ν•¨μˆ˜κ°€ λ°˜ν™˜λœ 후에도 μ™ΈλΆ€ ν•¨μˆ˜μ˜ λ³€μˆ˜ λ²”μœ„ 체인에 μ ‘κ·Όν•  수 μžˆλŠ” ν•¨μˆ˜μ΄λ‹€. μ „μ—­ λ³€μˆ˜μ˜ μ‚¬μš©μ„ μ–΅μ œν•˜κ³ , 정보λ₯Ό μ€λ‹‰ν•˜κΈ° μœ„ν•΄ μ‚¬μš©ν•œλ‹€.
728x90