Skip to content

Instantly share code, notes, and snippets.

@snaag
Last active May 14, 2020 12:39
Show Gist options
  • Save snaag/dcbe5bc630d3e2da8ea5d1930b79356b to your computer and use it in GitHub Desktop.
Save snaag/dcbe5bc630d3e2da8ea5d1930b79356b to your computer and use it in GitHub Desktop.

λ“€μ–΄κ°€λ©°

λ™μΌν•œ λ‚΄μš©μ΄ μžλ°”μŠ€ν¬λ¦½νŠΈ μŠ€ν„°λ”” μ‹œλ¦¬μ¦ˆμ— μžˆκΈ°λŠ” ν•˜μ§€λ§Œ, μžλ°”μŠ€ν¬λ¦½νŠΈ μ‹œλ¦¬μ¦ˆμ—λ„ 이 λ‚΄μš©μ„ λ„£κ³  μ‹Άμ–΄μ„œ 같은 글을 두 번 ν¬μŠ€νŒ…ν•˜κ²Œ λ˜μ—ˆλ‹€.

λ‚΄μš©

1. Scope

μŠ€μ½”ν”„λŠ” ν”νžˆ, λ³€μˆ˜μ˜ 생쑴 λ²”μœ„ 라고 μ•Œκ³  μžˆλ‹€. λ‚˜ λ˜ν•œ κ·Έλ ‡κ²Œλ§Œ μƒκ°ν•˜κ³  μžˆμ—ˆλ‹€. λ¬Όλ‘  이 말이 마λƒ₯ 틀린것은 μ•„λ‹ˆμ§€λ§Œ, μŠ€μ½”ν”„λŠ” 보닀 넓은 κ°œλ…μ„ ν¬ν•¨ν•˜λŠ” 단어이닀.

κ·Έλž˜μ„œ μŠ€μ½”ν”„λ₯Ό μ•ŒκΈ° 전에, μžλ°”μŠ€ν¬λ¦½νŠΈ ν”„λ‘œκ·Έλž¨μ΄ μ–΄λ–»κ²Œ μž‘λ™ν•˜λŠ”μ§€λ₯Ό λ¨Όμ € 볼것이닀.

μžλ°”μŠ€ν¬λ¦½νŠΈ ν”„λ‘œκ·Έλž¨μ€ μ–΄λ–»κ²Œ μ‹€ν–‰λ κΉŒ?

  • μžλ°”μŠ€ν¬λ¦½νŠΈ ν”„λ‘œκ·Έλž¨μ€ Engine, Compiler, Scope에 μ˜ν•΄ μ‹€ν–‰λœλ‹€. (보닀 μ •ν™•ν•˜κ²ŒλŠ” 엔진에 μ˜ν•΄ μ‹€ν–‰λ˜μ§€λ§Œ, μ»΄νŒŒμΌλŸ¬μ™€ μŠ€μ½”ν”„λŠ” μ—”μ§„μ˜ λͺ…령에 따라 각기 맑은 일을 ν•˜κΈ° λ•Œλ¬Έμ—, 각각에 μ˜ν•΄ μ‹€ν–‰λœλ‹€λŠ” 것도 마λƒ₯ ν‹€λ¦¬μ§€λ§Œμ€ μ•Šλ‹€κ³  μƒκ°ν•œλ‹€)

Engine

  • Compilation의 μ „ κ³Όμ •κ³Ό μžλ°”μŠ€ν¬λ¦½νŠΈ ν”„λ‘œκ·Έλž¨ μ‹€ν–‰μ˜ μ „ 과정을 λ‹΄λ‹Ήν•œλ‹€. (μš°λ¦¬κ°€ ν”νžˆ μ•„λŠ” V8은 μžλ°”μŠ€ν¬λ¦½νŠΈμ˜ λ‹€μ–‘ν•œ 엔진 쀑 ν•˜λ‚˜μ΄λ‹€)

Compiler (Do compilation)

  • μ»΄νŒŒμΌλ ˆμ΄μ…˜μ„ ν•œλ‹€. μ»΄νŒŒμΌλ ˆμ΄μ…˜μ΄λž€ 엔진이 μ‹€ν–‰ν•  수 μžˆλŠ” μ½”λ“œλ₯Ό μƒμ„±ν•˜λŠ” 과정을 λ§ν•œλ‹€.
  • μ»΄νŒŒμΌλ ˆμ΄μ…˜μ€ ν† ν¬λ‚˜μ΄μ§•/λ ‰μ‹±, νŒŒμ‹±, μ½”λ“œ 생성 의 총 3λ‹¨κ³„λ‘œ μ΄λ£¨μ–΄μ Έμžˆλ‹€.

μ˜ˆμ‹œμ™€ ν•¨κ»˜ 보자.

  • μ•„λž˜μ™€ 같은 μžλ°”μŠ€ν¬λ¦½νŠΈ ν”„λ‘œκ·Έλž¨μ΄ μžˆλ‹€.
  • 이해λ₯Ό 돕기 μœ„ν•΄ μž‘μ„±ν•œ κ±°λΌμ„œ μ‹€μ œμ™€ 쑰금 λ‹€λ₯΄λ‹€. 보닀 μ •ν™•ν•˜κ³  μžμ„Έν•˜κ²Œ μ•Œκ³ μ‹Άλ‹€λ©΄ 이 μ‚¬μ΄νŠΈλ₯Ό λ°©λ¬Έν•΄λ³΄μž.

1_default

ν† ν¬λ‚˜μ΄μ§•/λ ‰μ‹± (Tokenizing/Lexing)

  • λ¬Έμžμ—΄μ„ λ‚˜λˆ„μ–΄, token이라 ν•˜λŠ” 의미 μžˆλŠ” 쑰각으둜 λ‚˜λˆ„λŠ” 것을 λ§ν•œλ‹€.
  • 이 과정을 거치면, 그림처럼 const, a, =, 5, = 으둜 λ‚˜λ‰˜μ–΄μ§„λ‹€.

1_lexing

νŒŒμ‹± (Parsing)

  • 토큰 배열을 ν”„λ‘œκ·Έλž¨μ˜ 문법 ꡬ쑰λ₯Ό λ°˜μ˜ν•˜μ—¬ 트리 ꡬ쑰둜 λ§Œλ“œλŠ” 것을 λ§ν•œλ‹€. 이 과정을 거쳐 λ§Œλ“€μ–΄μ§„ 것을 AST(Abstract Syntax Tree) 라 ν•œλ‹€.
  • 이 과정을 거치면, κ·Έλ¦Όκ³Ό 같은 (λ˜‘κ°™μ§€λŠ” μ•Šλ‹€) ASTκ°€ μƒμ„±λœλ‹€.

1_ast

μ½”λ“œ 생성 (Code-Generation)

  • 엔진이 μ‹€ν–‰ν•  수 μžˆλŠ” μ½”λ“œλ₯Ό μƒμ„±ν•œλ‹€.

Scope

  • μŠ€μ½”ν”„λŠ” λ³€μˆ˜μ˜ μƒμ‘΄λ²”μœ„ λ₯Ό λ§ν•œλ‹€, 라고 ν•˜λ©΄ ν‹€λ¦° 말은 μ•„λ‹ˆλ‹€. ν•˜μ§€λ§Œ λ­”κ°€ 아쉬움이 μžˆλ‹€. μ™œλƒν•˜λ©΄ μŠ€μ½”ν”„λŠ” 이보닀 큰 κ°œλ…μ„ ν¬ν•¨ν•˜λŠ” 단어이기 λ•Œλ¬Έμ΄λ‹€.

μŠ€μ½”ν”„μ™€ λ³€μˆ˜

  • μ½”λ“œλ₯Ό μž‘μ„±ν•˜λŠ”λ™μ•ˆ λ‹€μ–‘ν•˜κ³  λ§Žμ€ λ³€μˆ˜λ“€μ΄ μ„ μ–Έλ˜κ³  ν• λ‹Ήλ˜κ³  μ‚¬μš©λœλ‹€. κ·Έλ ‡λ‹€λ©΄ ν”„λ‘œκ·Έλž¨μ€ μ–΄λ–€ λ³€μˆ˜κ°€ 어디에 μ €μž₯λ˜μ–΄μžˆλŠ”μ§€ μ–΄λ–»κ²Œ μ°ΎλŠ”κ±ΈκΉŒ? μ–΄λ–€ κ·œμΉ™μ΄ ν•„μš”ν•˜μ§€ μ•Šμ„κΉŒ?
  • μ΄λŸ¬ν•œ 일을 ν•˜λŠ” 것이 μŠ€μ½”ν”„μ΄λ‹€. 즉 μŠ€μ½”ν”„λŠ” 생쑴 λ²”μœ„ λ§Œμ„ λ§ν•˜λŠ” 것이 μ•„λ‹ˆλΌ, κ·œμΉ™μ— 따라 λ³€μˆ˜μ— κ΄€ν•œ λͺ©λ‘μ„ μž‘μ„±ν•˜κ³  κ΄€λ¦¬ν•˜λŠ” 것을 λ§ν•œλ‹€. λ”°λΌμ„œ μŠ€μ½”ν”„λŠ” λ³€μˆ˜μ˜ μƒμ‘΄λ²”μœ„λ₯Ό λ§ν•œλ‹€ λΌλŠ” μ •μ˜λŠ” 쑰금 아쉬움이 λ‚¨λŠ” 것이닀.

μ»΄νŒŒμΌλŸ¬μ™€ 엔진과 μŠ€μ½”ν”„κ°€ μ–΄λ–»κ²Œ μžλ°”μŠ€ν¬λ¦½νŠΈ ν”„λ‘œκ·Έλž¨μ„ μ‹€ν–‰ν•˜λŠ”μ§€λ₯Ό μ•Œμ•„λ³΄μž

  • 1번 μ½”λ“œμ™€ 2번 μ½”λ“œλŠ” 같은 역할을 μˆ˜ν–‰ν•œλ‹€.
  • 1번 μ½”λ“œλŠ” μ‚¬μš©μžκ°€ μž‘μ„±ν•œ μ½”λ“œμ΄κ³ , 2번 μ½”λ“œλŠ” 1번 μ½”λ“œκ°€ μ»΄νŒŒμΌλ ˆμ΄μ…˜μ„ 거치며 λ§Œλ“€μ–΄μ§„ 엔진이 μ‹€ν–‰μ‹œν‚¬ μ½”λ“œμ΄λ‹€. (μ™„μ „ λ˜‘κ°™μ§€λŠ” μ•Šμ§€λ§Œ, 의미적으둜 λΉ„μŠ·ν•˜λ‹€)
// 1
var a = 5; 
console.log(a); // 5
// 2
var a;
a = 5;

console.log(a);

엔진이 2번 μ½”λ“œ λ₯Ό μ‹€ν–‰ν•˜λŠ” λ™μ•ˆ, 무슨 일이 μΌμ–΄λ‚ κΉŒ?

  • var a; 이건 μ»΄νŒŒμΌλŸ¬κ°€ μ‹€ν–‰ν•˜λŠ” μ½”λ“œλ‘œ, μ»΄νŒŒμΌλŸ¬κ°€ μŠ€μ½”ν”„μ—κ²Œ λ³€μˆ˜ aκ°€ νŠΉμ •ν•œ μŠ€μ½”ν”„ μ»¬λ ‰μ…˜(a.k.a λ²”μœ„) μ•ˆμ— μžˆλŠ”μ§€λ₯Ό λ¬Όμ–΄λ³΄λŠ” 것이닀. 이미 μ»¬λ ‰μ…˜ μ•ˆμ— μžˆλ‹€λ©΄ λ¬΄μ‹œν•˜κ³  μ§€λ‚˜κ°€κ³ , μ—†λ‹€λ©΄ μ»΄νŒŒμΌλŸ¬κ°€ μŠ€μ½”ν”„μ—κ²Œ μŠ€μ½”ν”„ μ»¬λ ‰μ…˜μ— μΆ”κ°€ν•˜λΌκ³  μš”μ²­ν•œλ‹€.
  • a = 5; 이건 엔진이 μ‹€ν–‰ν•˜λŠ” μ½”λ“œλ‘œ, 엔진은 이 μ½”λ“œλ₯Ό μ²˜λ¦¬ν•˜λŠ” λ™μ•ˆ 두 κ°€μ§€μ˜ 일을 ν•œλ‹€.
    1. a λŠ” ν˜„μž¬ μŠ€μ½”ν”„ μ»¬λ ‰μ…˜ λ‚΄μ—μ„œ μ ‘κ·Όν•  수 μžˆλŠ”κ°€?
    2. κ·Έλ ‡λ‹€λ©΄ a μ—κ²Œ 5 λ₯Ό ν• λ‹Ήν•œλ‹€. (그렇지 μ•Šλ‹€λ©΄ λ‹€λ₯Έ 쀑첩 μŠ€μ½”ν”„λ₯Ό λ³Έλ‹€)
  • μ΄λ ‡κ²Œ aμ—κ²Œ 5κ°€ 할당이 λ˜μ—ˆλ‹€. 그리고 console.log(a); λ₯Ό μ‹€ν–‰ν•˜μ—¬ 5λ₯Ό 좜λ ₯ν•˜κ²Œ λ˜μ—ˆλ‹€.

κ·ΈλŸ¬λ‹ˆκΉŒ 엔진은 무엇을 ν•œκ±°λΌκ΅¬?

  • 값을 ν• λ‹Ήν•˜κ³  (a = 5;), 값을 λΆˆλŸ¬μ˜€λŠ” ν˜Ήμ€ μ ‘κ·Όν•˜λŠ” (console.log(a);) 두 κ°€μ§€μ˜ 일을 ν•œ 것이닀. 이것을 μ’€ 더 μžμ„Ένžˆ 보자.

ν• λ‹Ήν•˜κ³ , 뢈러였기

μ•žμ„  μ†ŒμŠ€λ‘œ ν•œ 일을 크게 λ‚˜λˆ„μ–΄μ„œ 생각해보면, 엔진은 ν• λ‹Ήν•˜λŠ” 것 a = 5; κ³Ό 값을 λΆˆλŸ¬μ™€μ„œ 좜λ ₯ν•˜λŠ” 것 console.log(a); 두 개의 일을 ν–ˆλ‹€.

  • LHS
    • LHS(Left-Hand Side) 검색이라 ν•˜λ©° 값을 ν• λ‹Ήν•  λ•Œ 엔진이 ν•˜λŠ” 검색이닀. λ³€μˆ˜κ°€ μ™Όμͺ½μ— μžˆμ„ λ•Œμ— μˆ˜ν–‰ν•˜λŠ” 것이닀. 즉 λ³€μˆ˜λ₯Ό ν• λ‹Ήν•  λ•Œ μΌμ–΄λ‚˜λŠ” 검색이 LHS 검색이닀.
  • 값을 μ°ΎλŠ”λ‹€. RHS
    • RHS(Right-Hand Side) 검색이라 ν•˜λ©° 값을 κ°€μ Έμ˜¬ λ•Œ 엔진이 ν•˜λŠ” 검색이닀. λ³€μˆ˜κ°€ 였λ₯Έμͺ½μ— μžˆμ„ λ•Œμ— μˆ˜ν–‰ν•˜λŠ” 것이닀. 즉 λ³€μˆ˜μ˜ 값을 κ°€μ Έμ˜¬ λ•Œ μΌμ–΄λ‚˜λŠ” 검색이 RHS 검색이닀.

μ •λ¦¬ν•΄λ³΄μž

  • νƒœμ΄ˆμ— 이 μ½”λ“œκ°€ μžˆμ—ˆλ‹€.
// 1
var a = 5; 
console.log(a); // 5
  • 그리고 μ»΄νŒŒμΌλ ˆμ΄μ…˜ 과정을 거치며, 이 μ½”λ“œ(엔진이 μ‹€ν–‰ν•  μ½”λ“œ)κ°€ λ˜μ—ˆλ‹€.
// 2
var a; // μ»΄νŒŒμΌλŸ¬κ°€ Scopeμ—κ²Œ 선언을 μš”μ²­ν•¨
a = 5; // 엔진이 LHS 검색을 함

console.log(a); // 엔진이 RHS 검색을 함

μ–΄ κ·ΈλŸ¬κ³ λ³΄λ‹ˆ.. μ»΄νŒŒμΌλ ˆμ΄μ…˜κ³Όμ •μ—μ„œ λͺ¨λ“  선언을 λ¨Όμ € ν•˜μž–μ•„? 그럼 hoxy... 이게 ν˜Έμ΄μŠ€νŒ…..?

  • κ·Έλ ‡λ‹€! 이게 ν˜Έμ΄μŠ€νŒ…μ΄λ‹€ ν˜Έμ΄μŠ€νŒ…!!

ν˜Έμ΄μŠ€νŒ…μ΄ 뭐더라..?

  • 잠깐 ν˜Έμ΄μŠ€νŒ…μ— λŒ€ν•΄ μ΄μ•ΌκΈ°ν•΄λ³΄μž. ν˜Έμ΄μŠ€νŒ…μ€ μ•žμ„œ 첫 μ£Ό 에 κ°„λ‹¨ν•˜κ²Œ μ–ΈκΈ‰ν–ˆλ˜ 것 처럼 선언문을 맨 μœ„λ‘œ λŒμ–΄μ˜¬λ¦¬λŠ” 것 이닀.

그래, 그럼 ν˜Έμ΄μŠ€νŒ…κ³Ό μ»΄νŒŒμΌλ ˆμ΄μ…˜ κ³Όμ •μ˜ 연관성에 λŒ€ν•΄ μ„€λͺ…ν•΄μ€˜

μžλ°”μŠ€ν¬λ¦½νŠΈ ν”„λ‘œκ·Έλž¨μ€ μ»΄νŒŒμΌκ³Όμ •μ„ κ±°μΉœλ‹€. 이 κ³Όμ •μ—μ„œ 엔진이 μ‹€ν–‰ν•  μ½”λ“œκ°€ λ§Œλ“€μ–΄μ§€κ³ , κ·Έ 후에야 엔진은 κ·Έ μ½”λ“œλ₯Ό μ‹€ν–‰ν•œλ‹€.

  • 이 말에 닡이 μžˆλ‹€. λ°”λ‘œ 컴파일 과정을 거치기 λ•Œλ¬Έμ΄λ‹€. 쑰금 더 μžμ„Ένžˆ λ§ν•˜μžλ©΄, 컴파일 κ³Όμ • 쀑에 μ»΄νŒŒμΌλŸ¬κ°€ λͺ¨λ“  μ„ μ–Έλ¬Έ(var a 와 같은) λ₯Ό 보고 μŠ€μ½”ν”„ μ»¬λ ‰μ…˜μ— 좔가해달라고 μš”μ²­μ„ λ¨Όμ € 해버리기 λ•Œλ¬Έμ΄λ‹€.
  • μ˜ˆμ‹œλ₯Ό 보자. 1번 μ½”λ“œκ°€ μš°λ¦¬κ°€ μž‘μ„±ν•œ μ½”λ“œμ΄κ³ , 2번 μ½”λ“œκ°€ 엔진이 μ‹€ν–‰ν•˜κ²Œ λ˜λŠ” μ½”λ“œμ΄λ‹€.
// 1
console.log(a); // undefined
var a;
// 2
var a; // ν˜Έμ΄μŠ€νŒ… λ˜μ—ˆλ‹€
console.log(a); // undefined
  • 2번 μ½”λ“œμ—μ„œ λ³΄λ‹€μ‹œν”Ό, 엔진이 μ‹€ν–‰ν•  λ•Œμ—λŠ” a 에 λŒ€ν•œ 선언이 λ˜μ–΄μžˆκΈ° λ•Œλ¬Έμ— ReferenceErorr κ°€ λ°œμƒν•˜μ§€ μ•Šκ³  undefined κ°€ λ°œμƒν•˜λŠ” 것이닀.

주의!!!

  • μ„ μ–Έλ¬Έλ§Œ 맨 μœ„λ‘œ 올리고, λŒ€μž…λ¬Έμ΄λ‚˜ 싀행문은 κ·ΈλŒ€λ‘œ λ‘”λ‹€.

κ·Έλ ‡λ‹€λ©΄ ReferenceError λŠ” μ–Έμ œ, μ™œ λ°œμƒν•˜λŠ”κ±ΈκΉŒ?

λ°œμƒν•˜λŠ” 경우λ₯Ό 보자

console.log(a); // ReferenceError
a = 5;
  • μœ„μ—μ„œ λ³Έ μ½”λ“œμ™€ λ³„λ‘œ λ‹€λ₯Έκ²ƒλ„μ—†λŠ”λ°, 이건 ReferenceError κ°€ λ‚œλ‹€. λ„λŒ€μ²΄ 뭐가 λ‹€λ₯Έκ±ΈκΉŒ?

    λ‚˜λ˜ν•œ μ§€λ‚œλ²ˆμ— 1μ£Όμ°¨ 자료λ₯Ό μ€€λΉ„ν•˜λ©΄μ„œ 두 μ½”λ“œμ˜ 차이점을 λͺ°λžμ—ˆκ³ , κ·Έλž˜μ„œ μ„œλ‘œ λ‹€λ₯Έ 결과에 ν˜Όλž€μŠ€λŸ¬μ› λ‹€.

undefined λ₯Ό 좜λ ₯ν•œ μœ„μ˜ μ½”λ“œμ™€ 무엇이 λ‹€λ₯Έκ±ΈκΉŒ? 거의 λ˜‘κ°™μ•„λ³΄μ΄λŠ”λ°?

  • λ°”λ‘œ 뭐가 λ‹€λ₯Έ 걸까? 선언문이 μ—†λ‹€!
    • μœ„ μ½”λ“œμ—μ„œ var a; λΌλŠ” λ¬Έμž₯은 μ—†μ—ˆλ‹€. 즉 컴파일 κ³Όμ •μ—μ„œ, μ»΄νŒŒμΌλŸ¬λŠ” μŠ€μ½”ν”„μ—κ²Œ a λ₯Ό μŠ€μ½”ν”„ μ»¬λ ‰μ…˜μ— 좔가해달라고 ν•˜μ§€ λͺ»ν•˜μ˜€λ‹€. κ·Έλ ‡κΈ° λ•Œλ¬Έμ—, μŠ€μ½”ν”„ μ»¬λ ‰μ…˜μ— a λŠ” μΆ”κ°€λ˜μ§€ λͺ»ν•˜μ˜€λ‹€!
    • 곧이어, console.log(a); λ₯Ό 엔진이 μ‹€ν–‰ν•˜λ©΄μ„œ μŠ€μ½”ν”„μ— μ—†λŠ” λ³€μˆ˜ a λ₯Ό μ–»μ–΄μ˜€λ €κ³ (RHS 검색) ν•˜μ˜€μœΌλ‹ˆ, μ‹€νŒ¨ ν•˜μ˜€λ‹€.
  • 즉 μœ„μ˜ λ‚΄μš©μ„ ν•œμ€„λ‘œ μš”μ•½ν•˜μžλ©΄, 'RHS 검색이 μ‹€νŒ¨ν•˜λ©΄ ReferenceError κ°€ λ°œμƒν•œλ‹€' 이닀.

그럼 const, let 의 κ²½μš°μ—λ„ ν˜Έμ΄μŠ€νŒ…μ΄ μΌμ–΄λ‚˜λ‚˜μš”? μ•ˆμΌμ–΄λ‚˜λŠ”κ±°κ°™λ˜λ°?

ν˜Έμ΄μŠ€νŒ…μ΄ μΌμ–΄λ‚˜μ§€ μ•Šμ€(것 처럼 λ³΄μ΄λŠ”) μ˜ˆμ‹œ μ½”λ“œ 좜처

console.log(a); // ReferenceError
let a = 20;
console.log(a);
  • 이 μ˜ˆμ‹œλ§Œ 봐도, ν˜Έμ΄μŠ€νŒ…μ΄ μΌμ–΄λ‚˜μ§€ μ•ŠλŠ” 것 κ°™λ‹€. 그런데 ν˜Έμ΄μŠ€νŒ…μ΄ μΌμ–΄λ‚œλ‹€λ‹ˆ? κ·Έλ ‡λ‹€λ©΄ λˆ„κ°€ ν˜Έμ΄μŠ€νŒ…μ΄ μ•ˆμΌμ–΄λ‚˜λŠ” 것 처럼 보이도둝 ν•΄μ£ΌλŠ”κ±΄κ°€?
    • κ·Έλ ‡λ‹€. TDZ λ•Œλ¬Έμ—, μœ„μ˜ 상황이 λ°œμƒν•˜μ—¬ ν˜Έμ΄μŠ€νŒ…μ΄ μΌμ–΄λ‚˜μ§€ μ•ŠλŠ” 것 처럼 λ³΄μ΄λŠ” 것이닀.

TDZ?

  • Temporal Dead Zone, μΌμ‹œμ  μ‚¬κ°μ§€λŒ€λ₯Ό λœ»ν•˜λŠ” 말이닀.
  • 이 곡간은 const, let으둜 μ„ μ–Έλœ λ³€μˆ˜κ°€ 할당이 되기 μ „κΉŒμ§€ 머무λ₯΄κ³  μžˆλŠ” 곳을 λ§ν•œλ‹€. 즉 할당이 되면, 이 κ³³μ—μ„œ λ²—μ–΄λ‚˜ μ°Έμ‘°(RHS) ν•  수 μžˆλŠ” μƒνƒœκ°€ λ˜λŠ” 것이닀.
  • 이와 같은 μ½”λ“œκ°€ μžˆλ‹€.
// 1
console.log(a); // ReferenceError
let a = 20;
console.log(a);
// 2
let a;
console.log(a); // ReferenceError
a = 20;
console.log(a);
  • μ•„κΉŒμ˜ 주석듀과 같이, 1번 μ½”λ“œκ°€ 원본 μ½”λ“œμ΄κ³  2번 μ½”λ“œκ°€ 엔진이 μ‹€ν–‰ν•  μ½”λ“œμ΄λ‹€.

1_tdzFlow_1

  • 사싀 μœ„μ—μ„œ a λŠ” 선언이 λ˜μ–΄μžˆμ—ˆλ‹€. κ·Έλ¦Όμ—μ„œ 보면 μŠ€μ½”ν”„ μ•ˆμ— λ“€μ–΄μžˆλŠ” 것을 λ³Ό 수 μžˆλ‹€. κ·ΈλŸ¬λ‚˜ λ³΄λ‹€μ‹œν”Ό TDZ μ•ˆμ— λ“€μ–΄μžˆλ‹€. μ™œλƒν•˜λ©΄ 아직 ν• λ‹Ήλ˜μ§€ μ•Šμ•˜κΈ° λ•Œλ¬Έ 이닀. λ•Œλ¬Έμ— RHS κ²€μƒ‰μœΌλ‘œ a λ₯Ό 찾을 수 μ—†μ—ˆκ³ , 이에 ReferenceError κ°€ λ°œμƒν•˜μ˜€λ‹€.

1_tdzFlow_2

  • 이제 a = 20; 을 λ§Œλ‚˜λ©°, a μ—κ²Œ 20 이 ν• λ‹Ήλ˜μ—ˆλ‹€. λ”°λΌμ„œ a λŠ” TDZ μ—μ„œ λΉ μ Έλ‚˜μ˜€κ²Œ λ˜μ—ˆλ‹€.

1_tdzFlow_3

  • 이제 console.log(a); λ₯Ό ν•˜κΈ° μœ„ν•΄, a λ₯Ό RHS κ²€μƒ‰ν•˜μ˜€μ„ λ•Œ μŠ€μ½”ν”„μ—μ„œ a λ₯Ό 찾을 수 있게 λ˜μ—ˆλ‹€.
  • κ·ΈλŸ¬λ‚˜ μœ„ μ½”λ“œλŠ”, μ‹€μ œ μž‘λ™μ‹œν‚¨λ‹€λ©΄ 두 λ²ˆμ§Έμ™€ μ„Έ 번째 의 κ²°κ³ΌλŠ” λ³Ό 수 μ—†λ‹€. μ™œλƒν•˜λ©΄, 첫 λ²ˆμ§Έμ—μ„œ ReferenceError κ°€ λ°œμƒν•˜μ˜€κΈ° λ•Œλ¬Έμ΄λ‹€. κ·Έλž˜μ„œ 이 μ½”λ“œμ— try ~ catch λ₯Ό μΆ”κ°€ν•˜μ—¬, μ—λŸ¬κ°€ λ°œμƒν•˜μ—¬λ„ μ‹€ν–‰λ˜λ„λ‘ λ§Œλ“€μ–΄λ³΄μ•˜λ‹€.
try {
	console.log(a);
}
catch (e) {
   console.log(e); // μ—λŸ¬ 좜λ ₯
}
let a = 20;
console.log(a);
ReferenceError: a is not defined
    at Object.<anonymous> (/Users/isang-a/Desktop/run.js:2:14)
    at Module._compile (module.js:653:30)
    at Object.Module._extensions..js (module.js:664:10)
    at Module.load (module.js:566:32)
    at tryModuleLoad (module.js:506:12)
    at Function.Module._load (module.js:498:3)
    at Function.Module.runMain (module.js:694:10)
    at startup (bootstrap_node.js:204:16)
    at bootstrap_node.js:625:3
20
  • 20이 잘 좜λ ₯λ˜λŠ” 것을 λ³Ό 수 μžˆμ—ˆλ‹€.

TDZ의 μ˜ˆμ‹œλ₯Ό μ½”λ“œλ‘œ 보자 μ½”λ“œ 좜처

  • κ·ΈλŸΌμ—λ„ 감이 μ•ˆ 올 수 μžˆμœΌλ‹ˆ, μ½”λ“œλ₯Ό 보자.
let a = 5;
{
  console.log(a);
}

{
  console.log(a); // undefined
  let a = 10;
}
  • λ†€λžκ²Œλ„ 5κ°€ μ•„λ‹ˆλΌ undefinedκ°€ 좜λ ₯λœλ‹€. κ·Έ μ΄μœ λŠ” λ°”λ‘œ μ½”λ“œκ°€ μ»΄νŒŒμΌλ ˆμ΄μ…˜ 과정을 거치며 μ•„λž˜μ²˜λŸΌ λ°”λ€ŒκΈ° λ•Œλ¬Έμ΄λ‹€.
let a = 5;
{
  console.log(a);
}

{
  let a; // ν˜Έμ΄μŠ€νŒ…μ΄ λ˜μ—ˆλ‹€
  console.log(a);
  a = 10;
}

정리

  • 즉 ν˜Έμ΄μŠ€νŒ…μ€ μ»΄νŒŒμΌλ ˆμ΄μ…˜ κ³Όμ • 쀑에, μ»΄νŒŒμΌλŸ¬κ°€ λͺ¨λ“  선언문을 보고 μŠ€μ½”ν”„μ—κ²Œ ν•΄λ‹Ή μ»¬λ ‰μ…˜μ— 선언을 엔진이 μ½”λ“œλ₯Ό μ‹€ν–‰ν•˜κΈ° μ „μ—μš”μ²­ν•˜κΈ° λ•Œλ¬Έμ— μΌμ–΄λ‚˜λŠ” 것이닀.
  • const, let λͺ¨λ‘ ν˜Έμ΄μŠ€νŒ…μ΄ μΌμ–΄λ‚˜λ‚˜, TDZ λ•Œλ¬Έμ— 우리 λˆˆμ—λŠ” μΌμ–΄λ‚˜μ§€ μ•ŠλŠ” 것 처럼 보인닀.

Lexical scope

λ ‰μ‹œμ»¬ μŠ€μ½”ν”„? 그게뭐죠?

  • μ»΄νŒŒμΌλ ˆμ΄μ…˜ κ³Όμ • 쀑 κ±°μΉ˜λŠ” 단계인 λ ‰μ‹± νƒ€μž„μ— κ²°μ •λ˜λŠ” μŠ€μ½”ν”„λ₯Ό λ§ν•œλ‹€. 즉 μ½”λ“œμ— 따라 λ§Œλ“€μ–΄μ§€λŠ” μŠ€μ½”ν”„λ₯Ό λ§ν•œλ‹€.

λ ‰μ‹œμ»¬ μŠ€μ½”ν”„λ₯Ό μ†μ΄λŠ” 방법

  • 일단 λ¨Όμ € λ§ν•˜μžλ©΄, μ΄λŠ” 컴파일 λ‹¨κ³„μ—μ„œ 미리 λ§Œλ“€μ–΄ 놓은 엔진이 μ‹€ν–‰ ν•  μ΅œμ ν™”λœ μ½”λ“œλ₯Ό μ˜λ―Έμ—†κ²Œ λ§Œλ“€κΈ° λ•Œλ¬Έμ— μ ˆλŒ€ 쒋은 방법이 μ•„λ‹ˆλ‹€. ν•˜μ§€λ§Œ λ ‰μ‹œμ»¬ μŠ€μ½”ν”„λ₯Ό κ³ μΉœλ‹€λŠ” 것이 무엇인지, μ–΄λ–€ κ²°κ³Όλ₯Ό μ΄ˆλž˜ν•˜λŠ”μ§€λ₯Ό 보기 μœ„ν•΄ 짚고 λ„˜μ–΄κ°€μž.
eval()
function foo(str, a) {
  eval(str);
  console.log(a, b);
}

var b = 2;
foo("var b=3;", 1); // 1, 3
  • 이 μ½”λ“œλ‘œ λ°”λ‘œ μ–΄λ–»κ²Œ μŠ€μ½”ν”„κ°€ κΌ¬μ˜€λŠ”μ§€ μ•Œμ•„λ³΄κΈ°μ—λŠ” 쑰금 μ–΄λ ΅λ‹€. eval() 이 μ‘΄μž¬ν•˜μ§€ μ•ŠλŠ” μ½”λ“œλ₯Ό λ¨Όμ € 보자. κ·Έ μ•„λž˜λŠ” 엔진이 μ‹€ν–‰ν•  μ½”λ“œμ΄λ‹€.
// eval()이 μ‘΄μž¬ν•˜μ§€ μ•ŠλŠ” μ½”λ“œ
function foo(a) {
  console.log(a, b);
}

var b = 2;
foo(1); // 1, 2
// 엔진이 μ‹€ν–‰ν•  μ½”λ“œ
var b;
function foo(a) {
  console.log(a, b);
}

b = 2;
foo(1); // 1, 2

1_eval_correct_1

1_eval_correct_2

  • b=2 λ₯Ό λ§Œλ‚˜κ³ , b에 2κ°€ ν• λ‹Ήλ˜μ—ˆλ‹€.

1_eval_correct_3

  • foo(1);을 호좜 ν•˜μ—¬ LHS 검색(a=1)을 ν•˜μ˜€λ‹€. 즉 aμ—κ²Œ 1을 ν• λ‹Ήν•΄ μ£Όμ—ˆλ‹€.

  • λ‹€μŒμœΌλ‘œ console.log(a, b); κ°€ μ‹€ν–‰λœλ‹€. 이 κ³Όμ •μ—μ„œ a λŠ” foo()의 μŠ€μ½”ν”„ μ•ˆμ— μžˆμœΌλ‹ˆ 1이 좜λ ₯이 될 것이닀. bλŠ” foo() 의 μŠ€μ½”ν”„μ— μ—†λ‹€. 이에 엔진이 더 μœ„μ˜ μŠ€μ½”ν”„λ₯Ό μ˜¬λΌκ°‘λ‹ˆλ‹€. λ°”λ‘œ μ „μ—­ μŠ€μ½”ν”„μ΄λ‹€. 그리고 이 κ³³μ—μ„œ bλ₯Ό μ°Ύμ•˜λ‹€. bλŠ” 2λ₯Ό κ°–λŠ”λ‹€. 즉 console.log(a, b); 의 κ²°κ³ΌλŠ” 1, 2 이닀.

  • λ‹€μ‹œ eval이 μžˆλŠ” μ½”λ“œλ₯Ό 보자.

// eval()이 μžˆλŠ” μ½”λ“œ
function foo(str, a) {
  eval(str);
  console.log(a, b);
}

var b = 2;
foo("var b=3;", 1); 
// 엔진이 μ‹€ν–‰ν•  μ½”λ“œ
var b;
function foo(str, a) {
  eval(str);
  console.log(a, b);
}

b = 2;
foo("var b=3;", 1); 

1_eval_wrong_1

1_eval_wrong_2

  • b=2; λ₯Ό μ‹€ν–‰ν–ˆλ‹€.

1_eval_wrong_3

  • foo("var b=3;", 1); λ₯Ό μ‹€ν–‰ν•œλ‹€. 이 κ³Όμ •μ—μ„œ bμ—λŠ” 3이 ν• λ‹Ήλ˜κ³ , aμ—λŠ” 1이 ν• λ‹Ήλœλ‹€. 즉 μ²˜μŒμ— λ§Œλ“€μ–΄ 놓은 μŠ€μ½”ν”„λ₯Ό 고치게 λœλ‹€.
with

μΆ”κ°€μ μœΌλ‘œ κ³ λ―Όν•œ 것

  1. JavaScriptλŠ” 컴파일 μ–Έμ–΄μΌκΉŒμš”, 인터프리터 μ–Έμ–΄μΌκΉŒμš”? JIT μ»΄νŒŒμΌλŸ¬λž€?
  • λ¨Όμ € 이 뢀뢄에 λŒ€ν•΄ μ•Œκ³  μ‹Άμ–΄ ꡬ글링을 ν•΄λ³΄μ•˜μŠ΅λ‹ˆλ‹€. κ·ΈλŸ¬λ‚˜ λͺ…ν™•ν•œ 해닡을 얻을 μˆ˜κ°€ μ—†μ—ˆμŠ΅λ‹ˆλ‹€. λˆ„κ΅°κ°€λŠ” 컴파일 μ–Έμ–΄λ‹€, λ‹€λ₯Έ λˆ„κ΅°κ°€λŠ” 인터프리터 언어이닀, 또 λ‹€λ₯Έ λˆ„κ΅°κ°€λŠ” 이 λ‘˜μ˜ 경계가 λͺ¨ν˜Έν•œ 언어이닀 λΌκ³ ν•˜μ˜€μŠ΅λ‹ˆλ‹€. μ΄λŠ” ꡉμž₯히 νŠΉμ΄ν•˜κ³ , λ‹Ήν™©μŠ€λŸ½κ³ , λ†€λž„λ§Œν•œ μΌμ΄μ—ˆμŠ΅λ‹ˆλ‹€. μ™œλƒν•˜λ©΄ C, Java, Pythonλ“± μ œκ°€ κ²½ν—˜ν•΄λ³Έ μ—¬λŸ¬ 언어듀은 μ»΄νŒŒμΌμ–Έμ–΄ ν˜Ήμ€ 인터프리터 μ–Έμ–΄λ‘œ λͺ…ν™•ν•˜κ²Œ κ΅¬λΆ„λ˜μ—ˆκΈ° λ•Œλ¬Έμ΄μ—ˆμŠ΅λ‹ˆλ‹€.
  • λ•Œλ¬Έμ— μ—¬λŸ¬ 자료λ₯Ό μ°Ύμ•„λ³΄μ•˜κ³ , 제 λ‚˜λ¦„λŒ€λ‘œ λ‚΄λ¦° μž μ •μ μΈ 결둠은 μžλ°”μŠ€ν¬λ¦½νŠΈλŠ” μΈν„°ν”„λ¦¬νŒ…μ„ ν•˜λŠ” 컴파일 μ–Έμ–΄λΌλŠ” κ²ƒμž…λ‹ˆλ‹€.
    • λ¨Όμ € 컴파일 μ–Έμ–΄κ°€ κ°–λŠ” νŠΉμ„±μ„ μžλ°”μŠ€ν¬λ¦½νŠΈμ˜ μ–΄λŠ λΆ€λΆ„μ—μ„œ λ³Ό 수 μžˆλŠ”μ§€λ₯Ό λ³΄κ² μŠ΅λ‹ˆλ‹€. μ΄λŠ” 이 μžλ£Œμ— μžˆλŠ” ν˜Έμ΄μŠ€νŒ… 이 κ°€μž₯ μ μ ˆν•˜λ‹€κ³  μƒκ°ν•©λ‹ˆλ‹€. (ν˜Έμ΄μŠ€νŒ…μ— λŒ€ν•œ μ„€λͺ…은 μΆ”κ°€μ μœΌλ‘œ ν•˜μ§€ μ•Šκ² μŠ΅λ‹ˆλ‹€)
    • λ‹€μŒμœΌλ‘œ 인터프리터 μ–Έμ–΄κ°€ κ°–λŠ” νŠΉμ„±μ„ μžλ°”μŠ€ν¬λ¦½νŠΈμ˜ μ–΄λŠ λΆ€λΆ„μ—μ„œ λ³Ό 수 μžˆλŠ”μ§€λ₯Ό λ³΄κ² μŠ΅λ‹ˆλ‹€. μ΄λŠ” 이 μžλ£Œμ— μžˆλŠ” with와 eval(), 그리고 좔후에 λ‹€λ£° this의 바인딩이라고 μƒκ°ν•©λ‹ˆλ‹€. λ¨Όμ € with 와 eval() μž…λ‹ˆλ‹€. μ΄λ“€μ˜ λ¬Έμ œμ μ€ μ•žμ—μ„œ 닀룬 것 처럼 μ»΄νŒŒμΌλ ˆμ΄μ…˜ 쀑에 λ§Œλ“€μ–΄ 놓은 μ΅œμ ν™”λœ μŠ€μ½”ν”„λ₯Ό λŸ°νƒ€μž„μ—μ„œ κ³ μΉœλ‹€ λŠ” 것 μ΄μ—ˆμŠ΅λ‹ˆλ‹€. λ˜ν•œ this의 바인딩 μž…λ‹ˆλ‹€. this의 바인딩은 λŸ°νƒ€μž„μ—μ„œ μΌμ–΄λ‚©λ‹ˆλ‹€. λ”°λΌμ„œ λŸ°νƒ€μž„μ—μ„œ μŠ€μ½”ν”„λ₯Ό κ³ μΉœλ‹€ λŠ” 말과, λŸ°νƒ€μž„μ—μ„œ (바인딩이)μΌμ–΄λ‚œλ‹€λŠ” 말이, 인터프리터 μ–Έμ–΄λ‘œμ¨μ˜ νŠΉμ§•μ„ 잘 보여쀀닀고 μƒκ°ν•©λ‹ˆλ‹€.
  • 그리고 이듀을 κ°€λŠ₯ν•˜κ²Œλ” ν•˜λŠ” λ°μ—λŠ” JIT μ»΄νŒŒμΌλŸ¬κ°€ 있기 λ•Œλ¬Έμž…λ‹ˆλ‹€.
    • JIT 컴파일러λ₯Ό μ„€λͺ…ν•˜κΈ°μ— μ•žμ„œ, 컴파일 언어와 인터프리터 μ–Έμ–΄μ˜ μž₯단점을 κ°„λ‹¨ν•˜κ²Œ λ³΄κ² μŠ΅λ‹ˆλ‹€.
    • 컴파일 μ–Έμ–΄λŠ” μ½”λ“œλ₯Ό μ‹€ν–‰ν•˜κΈ° μ „, 컴파일 νƒ€μž„μ— μ½”λ“œμ˜ μ΅œμ ν™”λ₯Ό μ§„ν–‰ν•©λ‹ˆλ‹€. 이 κ³Όμ •μ—μ„œ 반볡문과 같은 μ½”λ“œμ˜ μ΅œμ ν™”κ°€ μΌμ–΄λ‚©λ‹ˆλ‹€. λ”°λΌμ„œ 컴파일 νƒ€μž„μ— 적지 μ•Šμ€ μ‹œκ°„μ„ μ“°μ§€λ§Œ, μ΅œμ ν™” 된 μ½”λ“œλ₯Ό μ‹€ν–‰ν•˜κΈ° λ•Œλ¬Έμ— μ‹€ν–‰ μ‹œκ°„μ€ μ§§μŠ΅λ‹ˆλ‹€.
    • 인터프리터 μ–Έμ–΄λŠ” μ΅œμ ν™”λ₯Ό ν•˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€. λŸ°νƒ€μž„μ— ν•œ 쀄, ν•œ 쀄 ν•΄μ„ν•˜λ©° μ‹€ν–‰ν•©λ‹ˆλ‹€. λ•Œλ¬Έμ— 컴파일 νƒ€μž„μ΄ μ‘΄μž¬ν•˜μ§€ μ•Šμ•„ 속도가 λΉ λ¦…λ‹ˆλ‹€. ν•˜μ§€λ§Œ 반볡문과 같이 같은 일을 μ—¬λŸ¬λ²ˆ λ°˜λ³΅ν•˜λŠ” μ½”λ“œμ˜ 경우, 맀 번 해석해야 ν•˜λ©° λ‹Ήμ—°νžˆ 이에 λŒ€ν•œ μ΅œμ ν™”λœ μ½”λ“œλŠ” μ—†μŠ΅λ‹ˆλ‹€. λ•Œλ¬Έμ— 이런 경우 μ‹€ν–‰ μ‹œκ°„μ΄ 였래 걸리게 λ©λ‹ˆλ‹€.
    • 즉 컴파일 μ–Έμ–΄λŠ” μ€€λΉ„ μ‹œκ°„μ΄ 많이 ν•„μš”ν•œ λŒ€μ‹ , μ‹€ν–‰ν•  λ•Œμ—λŠ” 속도가 λΉ λ₯΄λ©° 인터프리터 μ–Έμ–΄λŠ” μ€€λΉ„ μ‹œκ°„μ΄ ν•„μš” μ—†μ§€λ§Œ κ²½μš°μ— 따라 속도가 많이 느렀질 수 μžˆλ‹€λŠ” κ²ƒμž…λ‹ˆλ‹€.
    • μ΄λ ‡κ²Œ μ„žμΌ 수 없을 것 같은 λ‘˜μ˜ μž₯, 단점을 JITλŠ” μ‘°ν™”λ‘­κ²Œ 잘 μ„žμ—ˆμŠ΅λ‹ˆλ‹€. λ°”λ‘œ λͺ¨λ‹ˆν„° λ₯Ό μ΄μš©ν•΄μ„œμš”. 이 λͺ¨λ‹ˆν„°λŠ” 인터프리터λ₯Ό μ‚¬μš©ν•˜μ—¬ μ½”λ“œλ₯Ό μ­‰ λ΄…λ‹ˆλ‹€. 그리고 자주 반볡이 μΌμ–΄λ‚˜λŠ” μ½”λ“œ, 즉 뜨거운(hot) μ½”λ“œ λ₯Ό μ°Ύμ•„λƒ…λ‹ˆλ‹€. 그리고 이 μ½”λ“œμ— λŒ€ν•΄μ„œλ§Œ μ»΄νŒŒμΌλŸ¬μ—κ²Œ μ΅œμ ν™”λ₯Ό μš”μ²­ν•©λ‹ˆλ‹€. μ΅œμ ν™”κ°€ ν•„μš”μ—†λŠ” μ½”λ“œμ— λŒ€ν•΄μ„œλŠ” μ΅œμ ν™”λ₯Ό ν•˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€. 즉 ν•„μš”ν•œ 뢀뢄에 λŒ€ν•΄μ„œλŠ” μ»΄νŒŒμΌμ„ ν•˜κ³ , 그렇지 μ•Šμ€ 뢀뢄은 ꡳ이 μ΅œμ ν™”λ₯Ό ν•˜μ§€ μ•Šκ³  μΈν„°ν”„λ¦¬νŒ…λ§Œ ν•©λ‹ˆλ‹€.
  • μ •λ¦¬ν•˜μžλ©΄, μ €λŠ” μžλ°”μŠ€ν¬λ¦½νŠΈλŠ” μΈν„°ν”„λ¦¬νŒ…μ„ ν•˜λŠ” 컴파일 언어라고 μƒκ°ν•˜λ©°, κ·Έ κΈ°μ €μ—λŠ” JIT μ»΄νŒŒμΌλŸ¬κ°€ 있기 λ•Œλ¬Έμ— κ°€λŠ₯ν•˜λ‹€κ³  μƒκ°ν•©λ‹ˆλ‹€.
  • μžλ°”μŠ€ν¬λ¦½νŠΈκ°€ 컴파일 μ–Έμ–΄, 인터프리터 μ–Έμ–΄μ˜ 성격을 λ‚˜νƒ€λ‚΄λŠ” 뢀뢄은 μ œκ°€ 닀룬 것 외에도 더 있으리라 μƒκ°ν•©λ‹ˆλ‹€. λ‹€λ§Œ μ œκ°€ 가진 μ§€μ‹μ˜ ν•œκ³„λ‘œ μ—¬κΈ°κΉŒμ§€λ§Œ 적어낸 것이 μ•„μ‰½μŠ΅λ‹ˆλ‹€. 이에 ν˜Ήμ‹œ λ‹€λ₯Έ μ˜ˆμ‹œλ‚˜ 의견이 μžˆμœΌμ‹œλ‹€λ©΄, 이슈λ₯Ό 남겨주신닀면 정말 κ°μ‚¬ν•˜κ² μŠ΅λ‹ˆλ‹€.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment