λ³Έλ¬Έ λ°”λ‘œκ°€κΈ°
πŸ“š Study Note/JavaScript

λͺ¨λ˜ μžλ°”μŠ€ν¬λ¦½νŠΈ Deep Dive - μ‹€ν–‰ μ»¨ν…μŠ€νŠΈ

by Jellll_y 2022. 12. 11.

μ‹€ν–‰ μ»¨ν…μŠ€νŠΈ 

μ‹€ν–‰ μ»¨ν…μŠ€νŠΈλ₯Ό μ•Œλ©΄ ν˜Έμ΄μŠ€νŒ…κ³Ό ν΄λ‘œμ €, μ½”λ“œ μ‹€ν–‰ μˆœμ„œλ₯Ό μ΄ν•΄ν•˜λŠ”λ° 도움이 되기 λ•Œλ¬Έμ— μ •λ¦¬ν•©λ‹ˆλ‹€.

 

μ†ŒμŠ€ μ½”λ“œμ˜ νƒ€μž… 

- μ „μ—­ μ½”λ“œ

μ „μ—­ λ³€μˆ˜λ₯Ό κ΄€λ¦¬ν•˜κΈ° μœ„ν•΄ μ΅œμƒμœ„ μŠ€μ½”ν”„μΈ μ „μ—­ μŠ€μ½”ν”„λ₯Ό μƒμ„±ν•œλ‹€.

 

- ν•¨μˆ˜ μ½”λ“œ

μ§€μ—­ μŠ€μ½”ν”„λ₯Ό μƒμ„±ν•˜κ³  μ§€μ—­λ³€μˆ˜, λ§€κ°œλ³€μˆ˜, arguments객체λ₯Ό κ΄€λ¦¬ν•œλ‹€.

 

- eval μ½”λ“œ

엄격 λͺ¨λ“œμ—μ„œ μžμ‹ λ§Œμ˜ λ…μžμ μΈ μŠ€μ½”ν”„λ₯Ό μƒμ„±ν•œλ‹€. 

 

- λͺ¨λ“ˆ μ½”λ“œ  

λͺ¨λ“ˆλ³„λ‘œ 독립적인 λͺ¨λ“ˆ μŠ€μ½”ν”„λ₯Ό μƒμ„±ν•œλ‹€.

 

μ†ŒμŠ€μ½”λ“œ(μ „μ—­, ν•¨μˆ˜, eval, λͺ¨λ“ˆ) → μ½”λ“œ 평가 → μ‹€ν–‰ μ»¨ν…μŠ€νŠΈ(μ „μ—­, ν•¨μˆ˜, eval, λͺ¨λ“ˆ) 

μ†ŒμŠ€ μ½”λ“œμ˜ 평가와 μ‹€ν–‰ 

μžλ°” 슀크립트 엔진은 μ†ŒμŠ€μ½”λ“œλ₯Ό 2개의 κ³Όμ •μœΌλ‘œ λ‚˜λˆ„μ–΄ μ²˜λ¦¬ν•œλ‹€ ( μ†ŒμŠ€μ½”λ“œ 평가, μ†ŒμŠ€μ½”λ“œ μ‹€ν–‰ )

 

- μ†ŒμŠ€ μ½”λ“œ 평가

μ‹€ν–‰ μ»¨ν…μŠ€νŠΈ μƒμ„±ν•˜κ³  λ³€μˆ˜, ν•¨μˆ˜ λ“±μ˜ μ„ μ–Έλ¬Έλ§Œ λ¨Όμ € μ‹€ν–‰ν•˜μ—¬ μŠ€μ½”ν”„μ— λ“±λ‘ν•œλ‹€.

 

- μ†ŒμŠ€ μ½”λ“œμ˜ μ‹€ν–‰ ( λŸ°νƒ€μž„ )

μ†ŒμŠ€ μ½”λ“œκ°€ 순차적으둜 μ‹€ν–‰λ˜λ©°, μ΄λ•Œ ν•„μš”ν•œ μ •λ³΄λŠ” μ‹€ν–‰ μ»¨ν…μŠ€νŠΈκ°€ κ΄€λ¦¬ν•˜λŠ” μŠ€μ½”ν”„μ—μ„œ κ²€μƒ‰ν•΄μ„œ μ·¨λ“ν•œλ‹€.

μ‹€ν–‰ 이후 κ²°κ³ΌλŠ” λ‹€μ‹œ μ‹€ν–‰ μ»¨ν…μŠ€νŠΈκ°€ κ΄€λ¦¬ν•˜λŠ” μŠ€μ½”ν”„μ— λ“±λ‘ν•œλ‹€.

 

μ†ŒμŠ€μ½”λ“œμ˜ 평가    μ‹€ν–‰ μ»¨ν…μŠ€νŠΈ 생성    μ†ŒμŠ€μ½”λ“œμ˜ μ‹€ν–‰    μ‹€ν–‰ μ»¨ν…μŠ€νŠΈμ˜ μŠ€μ½”ν”„μ— 등둝

 

var x
x = 1
μ‹€ν–‰ μ»¨ν…μŠ€νŠΈ
x undefined
 ν‰κ°€

μ‹€ν–‰ μ»¨ν…μŠ€νŠΈ
x 1

μ‹€ν–‰

 

μ‹€ν–‰ μ»¨ν…μŠ€νŠΈμ˜ μ—­ν•  및 μŠ€νƒ

μ†ŒμŠ€μ½”λ“œλ₯Ό μ‹€ν–‰ν•˜λŠ”λ° ν•„μš”ν•œ ν™˜κ²½μ„ μ œκ³΅ν•˜κ³  μ½”λ“œμ˜ μ‹€ν–‰ κ²°κ³Όλ₯Ό μ‹€μ œλ‘œ κ΄€λ¦¬ν•œλ‹€. 

 

μ‹λ³„μžλ₯Ό λ“±λ‘ν•˜κ³  κ΄€λ¦¬ν•˜λŠ” μŠ€μ½”ν”„μ™€ μ½”λ“œ μ‹€ν–‰ μˆœμ„œ 관리λ₯Ό κ΅¬ν˜„ν•œ λ‚΄λΆ€ λ©”μ»€λ‹ˆμ¦˜μœΌλ‘œ, 

λͺ¨λ“  μ½”λ“œλŠ” μ‹€ν–‰ μ»¨ν…μŠ€νŠΈλ₯Ό 톡해 μ‹€ν–‰λ˜κ³  κ΄€λ¦¬λœλ‹€.

 

μ‹λ³„μžμ™€ μŠ€μ½”ν”„λŠ” μ‹€ν–‰ μ»¨ν…μŠ€νŠΈμ˜ λ ‰μ‹œμ»¬ ν™˜κ²½μœΌλ‘œ κ΄€λ¦¬ν•œλ‹€.

μ½”λ“œ μ‹€ν–‰ μˆœμ„œλŠ” μ‹€ν–‰ μ»¨ν…μŠ€νŠΈ μŠ€νƒμœΌλ‘œ κ΄€λ¦¬ν•œλ‹€.

+ μ΅œμƒμœ„μ— μ‘΄μž¬ν•˜λŠ” μ‹€ν–‰ μ»¨ν…μŠ€νŠΈλ₯Ό μ‹€ν–‰ 쀑인 μ‹€ν–‰ μ»¨ν…μŠ€νŠΈλΌκ³  ν•œλ‹€.

const x = 1

function foo(a){
    const x = 10
    const y = 20
    
    console.log(a + y)
}

foo(100)

console.log(x)

 

μœ„μ˜ μ½”λ“œμ˜ μ‹€ν–‰ μ»¨ν…μŠ€νŠΈ μˆœμ„œλ₯Ό 예둜 λ“€λ©΄

1. μ „μ—­ μ½”λ“œ 평가 (μ „μ—­ μ‹€ν–‰ μ»¨ν…μŠ€νŠΈλ₯Ό μƒμ„±ν•˜κ³  μ‹€ν–‰ μ»¨ν…μŠ€νŠΈ μŠ€νƒμ— ν‘Έμ‹œ)

μ „μ—­ λ³€μˆ˜μ™€ μ „μ—­ ν•¨μˆ˜κ°€ μ „μ—­ μŠ€μ½”ν”„μ— λ“±λ‘λœλ‹€. 

μ΄λ•Œ, var둜 μ„ μ–Έν•œ μ „μ—­ λ³€μˆ˜μ™€ function으둜 μ„ μ–Έλœ ν•¨μˆ˜λŠ” μ „μ—­ 객체의 ν”„λ‘œνΌν‹°μ™€ λ©”μ„œλ“œκ°€ λœλ‹€.

 

2. μ „μ—­ μ½”λ“œ μ‹€ν–‰ ( foo ν•¨μˆ˜κ°€ ν˜ΈμΆœλ˜λ©΄μ„œ μ‹€ν–‰ μ»¨ν…μŠ€νŠΈ μŠ€νƒμ— foo ν•¨μˆ˜ μ‹€ν–‰ μ»¨ν…μŠ€νŠΈ ν‘Έμ‹œ)

λŸ°νƒ€μž„μ΄ μ‹œμž‘λ˜μ–΄ μ½”λ“œκ°€ 순차적으둜 ν‰κ°€λœλ‹€.

μ°¨λ‘€λŒ€λ‘œ μ „μ—­ λ³€μˆ˜μ— 값이 ν• λ‹Ήλ˜κ³  ν•¨μˆ˜κ°€ ν˜ΈμΆœλœλ‹€. ( ν•¨μˆ˜κ°€ 호좜되면 ν•¨μˆ˜ λ‚΄λΆ€λ‘œ μ΄λ™ν•œλ‹€)

 

3. ν•¨μˆ˜ μ½”λ“œ 평가 

이것도 μ•žμ˜ κ³Όμ •κ³Ό λ˜‘κ°™μ΄ μš°μ„  평가λ₯Ό λ¨Όμ € ν•œλ‹€. ( λ§€κ°œλ³€μˆ˜, μ§€μ—­λ³€μˆ˜ μ„ μ–Έ 및 μ§€μ—­ μŠ€μ½”ν”„μ— 등둝)

 

4. ν•¨μˆ˜ μ½”λ“œ μ‹€ν–‰ ( foo ν•¨μˆ˜κ°€ μ‹€ν–‰ μ’…λ£Œλ˜λ©° μ‹€ν–‰ μ»¨ν…μŠ€νŠΈ μŠ€νƒμ—μ„œ pop ν•œλ‹€)

λŸ°νƒ€μž„μ΄ μ‹œμž‘λ˜μ–΄ ν•¨μˆ˜ μ½”λ“œκ°€ 순차적으둜 μ‹€ν–‰λœλ‹€. 

μ΄λ•Œ μ‹λ³„μžλ“€μ— 값이 ν• λ‹Ήλ˜κ³ , μŠ€μ½”ν”„ 체인을 톡해 μ‹λ³„μžλ₯Ό μ°Ύμ•„ 값을 좜λ ₯ν•œλ‹€.

 

5. μ „μ—­ μ½”λ“œ μ΄μ–΄μ„œ μ‹€ν–‰

λ§ˆμ§€λ§‰μœΌλ‘œ console.log(x)κ°€ μ‹€ν–‰λ˜κ³  λ‚˜μ„œ μ‹€ν–‰ μ»¨ν…μŠ€νŠΈμ—μ„œ μ „μ—­ μ‹€ν–‰ μ»¨ν…μŠ€νŠΈλ₯Ό pop ν•œλ‹€.

 

λ ‰μ‹œμ»¬ ν™˜κ²½ 

μ‹λ³„μžμ™€ μ‹λ³„μžμ— λ°”μΈλ”©λœ κ°’, 그리고 μƒμœ„ μŠ€μ½”ν”„μ— λŒ€ν•œ μ°Έμ‘°λ₯Ό κΈ°λ‘ν•˜λŠ” 자료ꡬ쑰둜 μ‹€ν–‰ μ»¨ν…μŠ€νŠΈλ₯Ό κ΅¬μ„±ν•˜λŠ” μ»΄ν¬λ„ŒνŠΈλ‹€. 

( 킀와 값을 κ°–λŠ” 객체 ν˜•νƒœμ˜ μŠ€μ½”ν”„λ₯Ό μƒμ„±ν•œλ‹€.)

 

λ ‰μ‹œμ»¬ ν™˜κ²½μ€ 두 개의 μ»΄ν¬λ„ŒνŠΈλ‘œ κ΅¬μ„±λœλ‹€.

 

1. ν™˜κ²½ λ ˆμ½”λ“œ (Environment Record)

μŠ€μ½”ν”„μ— ν¬ν•¨λœ μ‹λ³„μž 등둝 및 μ‹λ³„μžμ— λ°”μΈλ”©λœ 값을 κ΄€λ¦¬ν•˜λŠ” μ €μž₯μ†Œ

 

2. μ™ΈλΆ€ λ ‰μ‹œμ»¬ ν™˜κ²½μ— λŒ€ν•œ μ°Έμ‘° (Outer Lexical Environment Reference)

μƒμœ„ μŠ€μ½”ν”„λ₯Ό 가리킨닀.

 

μ‹€ν–‰ μ»¨ν…μŠ€νŠΈμ˜ 생성과 μ‹λ³„μž 검색 κ³Όμ • 

var x = 1
const y = 2

function foo (a) {
    var x = 3
    const y = 4
    
    function bar(b) {
        const z = 5
        console.log(a + b + x + y + z)
    }
    bar(10)
}

foo(20)

μœ„μ˜ μ½”λ“œλ₯Ό μ˜ˆμ‹œλ‘œ 전체 μ‹€ν–‰ μ»¨ν…μŠ€νŠΈμ˜ 생성과 μ‹λ³„μž 검색 과정을 μ‚΄νŽ΄λ³΄κ² μŠ΅λ‹ˆλ‹€. 

 

1. μ „μ—­ 객체 생성 

μ „μ—­ μ½”λ“œ 평가전 μ „μ—­ 객체가 λ¨Όμ € μƒμ„±λœλ‹€.

 

2. μ „μ—­ μ½”λ“œ 평가 

μ „μ—­ μ½”λ“œ 평과 과정은 λ‹€μŒκ³Ό κ°™λ‹€. 

  1. μ „μ—­ μ‹€ν–‰ μ»¨ν…μŠ€νŠΈ 생성 ( μ‹€ν–‰ μ»¨ν…μŠ€νŠΈ μŠ€νƒμ— push )
  2. μ „μ—­ λ ‰μ‹œμ»¬ ν™˜κ²½ 생성 ( μ „μ—­ λ ‰μ‹œμ»¬ ν™˜κ²½μ„ μƒμ„±ν•˜κ³  μ „μ—­ μ‹€ν–‰ μ»¨ν…μŠ€νŠΈμ— 바인딩, λ ‰μ‹œμ»¬ ν™˜κ²½μ€ ν™˜κ²½ λ ˆμ½”λ“œμ™€ μ™ΈλΆ€ λ ‰μ‹œμ»¬ ν™˜κ²½μ— λŒ€ν•œ μ°Έμ‘° 2κ°€μ§€λ‘œ κ΅¬μ„±λœλ‹€.)
    1. μ „μ—­ ν™˜κ²½ λ ˆμ½”λ“œ 생성 ( 객체 ν™˜κ²½ λ ˆμ½”λ“œμ™€ 선언적 ν™˜κ²½ λ ˆμ½”λ“œλ‘œ κ΅¬μ„±λœλ‹€.
      1. 객체 ν™˜κ²½ λ ˆμ½”λ“œ 생성 ( var ν‚€μ›Œλ“œλ‘œ μ„ μ–Έλœ μ „μ—­ λ³€μˆ˜ 및 ν•¨μˆ˜ μ„ μ–Έλ¬ΈμœΌλ‘œ μ •μ˜λœ μ „μ—­ ν•¨μˆ˜ 등둝)
      2. 선언적 ν™˜κ²½ λ ˆμ½”λ“œ 생성 ( let, const ν‚€μ›Œλ“œλ‘œ μ„ μ–Έλœ μ „μ—­ λ³€μˆ˜ 등둝)
  3. this 바인딩 ( ν•¨μˆ˜μ˜ 호좜 방식에 따라 λ‹€λ₯΄λ‹€)
  4. μ™ΈλΆ€ λ ‰μ‹œμ»¬ ν™˜κ²½μ— λŒ€ν•œ μ°Έμ‘° κ²°μ • ( μƒμœ„ μŠ€μ½”ν”„ ) 

 

- 객체 ν™˜κ²½ λ ˆμ½”λ“œ ( Object Environment Record) 

var ν‚€μ›Œλ“œλ‘œ μ„ μ–Έν•œ μ „μ—­ λ³€μˆ˜μ™€ ν•¨μˆ˜ μ„ μ–Έλ¬ΈμœΌλ‘œ μ •μ˜ν•œ μ „μ—­ ν•¨μˆ˜, 빌트인 μ „μ—­ ν”„λ‘œνΌν‹°μ™€ 빌트인 μ „μ—­ ν•¨μˆ˜, ν‘œμ€€ 빌트인 객체λ₯Ό κ΄€λ¦¬ν•œλ‹€.

 

- BindingObject 

μ „μ—­ 객체 

 

- 선언적 λ ˆμ½”λ“œ (Declarative Environment Record) 

let, const ν‚€μ›Œλ“œλ‘œ μ„ μ–Έν•œ μ „μ—­ λ³€μˆ˜λ₯Ό κ΄€λ¦¬ν•œλ‹€.

 

3. μ „μ—­ μ½”λ“œ μ‹€ν–‰ 

 

4. foo ν•¨μˆ˜ μ½”λ“œ 평가 ( μ „μ—­ μ½”λ“œ 평과 κ³Όμ •κ³Ό 동일 , μŠ€νƒμ— foo μ‹€ν–‰ μ»¨ν…μŠ€νŠΈ μΆ”κ°€ )

  1. ν•¨μˆ˜ μ‹€ν–‰ μ»¨ν…μŠ€νŠΈ 생성
  2. ν•¨μˆ˜ λ ‰μ‹œμ»¬ ν™˜κ²½ 생성
    1. ν•¨μˆ˜ ν™˜κ²½ λ ˆμ½”λ“œ 생성 ( λ§€κ°œλ³€μˆ˜, arguments 객체, ν•¨μˆ˜ λ‚΄λΆ€μ˜ μ§€μ—­ λ³€μˆ˜μ™€ 쀑첩 ν•¨μˆ˜ 등둝 )
    2. this 바인딩
    3. μ™ΈλΆ€ λ ‰μ‹œμ»¬ ν™˜κ²½μ— λŒ€ν•œ μ°Έμ‘° κ²°μ •

 

5. foo ν•¨μˆ˜ μ½”λ“œ μ‹€ν–‰ 

 

6. bar ν•¨μˆ˜ μ½”λ“œ 평가  ( foo ν•¨μˆ˜ μ½”λ“œ 평가 κ³Όμ •κ³Ό λ™μΌ , μ‹€ν–‰ μ»¨ν…μŠ€νŠΈ μŠ€νƒμ— bar μ‹€ν–‰ μ»¨ν…μŠ€νŠΈ μΆ”κ°€ )

 

7. bar ν•¨μˆ˜ μ½”λ“œ μ‹€ν–‰  

 

9. bar ν•¨μˆ˜ μ½”λ“œ μ‹€ν–‰ μ’…λ£Œ ( μŠ€νƒμ—μ„œ bar μ‹€ν–‰ μ»¨ν…μŠ€νŠΈ 제거 )

 

10. foo ν•¨μˆ˜ μ½”λ“œ μ‹€ν–‰ μ’…λ£Œ ( μŠ€νƒμ—μ„œ foo μ‹€ν–‰ μ»¨ν…μŠ€νŠΈ 제거 ) 

 

11. μ „μ—­ μ½”λ“œ μ‹€ν–‰ μ’…λ£Œ ( μŠ€νƒμ—μ„œ μ „μ—­ μ‹€ν–‰ μ»¨ν…μŠ€νŠΈ 제거 ) 

 

ν˜Έμ΄μŠ€νŒ…

μ•žμ—μ„œ μ •λ¦¬ν•œ μ‹€ν–‰ μ»¨ν…μŠ€νŠΈλ‘œ ν˜Έμ΄μŠ€νŒ…λ₯Ό μ„€λͺ…ν•˜κ² μŠ΅λ‹ˆλ‹€.

 

- ν˜Έμ΄μŠ€νŒ…

 

ν˜Έμ΄μŠ€νŒ…μ΄λž€ 선언문이 λŸ°νƒ€μž„ 전에 μŠ€μ½”ν”„ μ΅œμƒλ‹¨μœΌλ‘œ λŒμ–΄μ˜¬λ €μ§€λŠ” 것을 λ§ν•œλ‹€.

μ΄λ•Œ var ν‚€μ›Œλ“œμ™€ let, const ν‚€μ›Œλ“œλ‘œ μ„ μ–Έν•œ λ³€μˆ˜λ“€μ˜ 호좜 μ‹œμ μ— λ”°λ₯Έ 값이 λ‹€λ₯Έλ°

이것을 μ‹€ν–‰ μ»¨ν…μŠ€νŠΈ λ‹¨κ³„λ³„λ‘œ μ‚΄νŽ΄λ³΄λ©° 이유λ₯Ό μ•Œμ•„λ³΄κ² μŠ΅λ‹ˆλ‹€. 

console.log(x) // undefined 
var x = 1 

console.log(x)

console.log(y) // μ°Έμ‘° μ—λŸ¬
let y = 1 
console.log(y) // 1

1. μ „μ—­ μ½”λ“œ 평가

var ν‚€μ›Œλ“œλ‘œ μ„ μ–Έλœ xλŠ” 평가 κ³Όμ •μ—μ„œ μ„ μ–Έκ³Ό μ΄ˆκΈ°ν™”λ₯Ό 같이 μ§„ν–‰ν•©λ‹ˆλ‹€ (undefined)

let ν‚€μ›Œλ“œλ‘œ μ„ μ–Έλœ yλŠ” 평가 κ³Όμ •μ—μ„œ μ„ μ–Έλ§Œ μ§„ν–‰ν•©λ‹ˆλ‹€.

 

μ „μ—­ μ‹€ν–‰ μ»¨ν…μŠ€νŠΈ 
undefined 
y  

2. μ „μ—­ μ½”λ“œ μ‹€ν–‰

λŸ°νƒ€μž„μ΄ μ‹œμž‘λ˜μ–΄ μ „μ—­ μ½”λ“œκ°€ 순차적으둜 μ‹€ν–‰λ©λ‹ˆλ‹€.

1. console.log(x) μ‹€ν–‰,  μ΄λ•Œ ν˜„μ œ ν™˜κ²½ λ ˆμ½”λ“œμ—μ„œ μ‹λ³„μž xλ₯Ό μ°Ύκ³  undefinedλ₯Ό 좜λ ₯ν•œλ‹€.

2. x의 값에 1을 ν• λ‹Ήν•œλ‹€.

3. console.log(x) μ‹€ν–‰, ν˜„μž¬ ν™˜κ²½ λ ˆμ½”λ“œμ—μ„œ μ‹λ³„μž xλ₯Ό μ°Ύκ³  1을 좜λ ₯ν•œλ‹€.

4. console.log(y) μ‹€ν–‰, ν˜„μž¬ ν™˜κ²½ λ ˆμ½”λ“œμ—μ„œ μ‹λ³„μž yλ₯Ό μ°Ύμ§€λ§Œ 값이 μ—†κΈ° λ•Œλ¬Έμ— μ°Έμ‘° μ—λŸ¬ λ°œμƒν•œλ‹€.

5. y의 값에 1을 ν• λ‹Ήν•œλ‹€.

6. console.log(y) μ‹€ν–‰, ν˜„μž¬ ν™˜κ²½ λ ˆμ½”λ“œμ—μ„œ μ‹λ³„μž yλ₯Ό μ°Ύκ³  1을 좜λ ₯ν•œλ‹€.

 

μœ„μ˜ 과정을 톡해 TDZκ°€ λ°œμƒν•˜λŠ” μ΄μœ μ™€, var ν‚€μ›Œλ“œλ‘œ λ³€μˆ˜ μ„ μ–Έ μ‹œ λ³€μˆ˜ μ„ μ–Έ μ „ 호좜이 λ˜λŠ” 이유λ₯Ό μ•Œ 수 μžˆμŠ΅λ‹ˆλ‹€.