관리 메뉴

Daehyunii's Dev-blog

15μž₯ let, const ν‚€μ›Œλ“œμ™€ 블둝 레벨 μŠ€μ½”ν”„ λ³Έλ¬Έ

πŸ“š Language & CS knowledge/JavaScript (λͺ¨λ˜μžλ°”μŠ€ν¬λ¦½νŠΈ Deep Dive)

15μž₯ let, const ν‚€μ›Œλ“œμ™€ 블둝 레벨 μŠ€μ½”ν”„

Daehyunii 2022. 7. 6. 17:58

15.1 var ν‚€μ›Œλ“œλ‘œ μ„ μ–Έν•œ λ³€μˆ˜μ˜ 문제점 

  ES5κΉŒμ§€ λ³€μˆ˜λ₯Ό μ„ μ–Έν•  수 μžˆλŠ” μœ μΌν•œ 방법은 var ν‚€μ›Œλ“œλ₯Ό μ‚¬μš©ν•˜λŠ” κ²ƒμ΄μ—ˆλ‹€. var ν‚€μ›Œλ“œλ‘œ μ„ μ–Έλœ λ³€μˆ˜λŠ” λ…νŠΉν•œ νŠΉμ§•μ΄ μžˆλ‹€.

 

15.1.1 λ³€μˆ˜ 쀑볡 μ„ μ–Έ ν—ˆμš©

  var ν‚€μ›Œλ“œλ‘œ μ„ μ–Έν•œ λ³€μˆ˜λŠ” 쀑볡 선언이 κ°€λŠ₯ν•˜λ‹€.

var x = 1; // λ³€μˆ˜ μ„ μ–Έ 및 κ°’μ˜ ν• λ‹Ή

var x = 100; // μžλ°”μŠ€ν¬λ¦½νŠΈ 엔진에 μ˜ν•΄ var ν‚€μ›Œλ“œκ°€ λ¬΄μ‹œλ˜κ³  x λ³€μˆ˜μ— μž¬ν• λ‹Ήμ΄ 이뀄진닀.

console.log(x); // 100

15.1.2 ν•¨μˆ˜ 레벨 μŠ€μ½”ν”„

  μ•žμ—μ„œ μ •λ¦¬ν•œ λ‚΄μš©κ³Ό 같이 var ν‚€μ›Œλ“œλ‘œ μ„ μ–Έν•œ λ³€μˆ˜λŠ” μ˜€λ‘œμ§€ ν•¨μˆ˜μ˜ μ½”λ“œ λΈ”λ‘λ§Œμ„ 지역 μŠ€μ½”ν”„λ‘œ μΈμ •ν•œλ‹€. λ”°λΌμ„œ ν•¨μˆ˜ μ™ΈλΆ€μ—μ„œ var ν‚€μ›Œλ“œλ‘œ μ„ μ–Έν•œ λ³€μˆ˜λŠ” μ½”λ“œ 블둝 λ‚΄μ—μ„œ 선언해도 λͺ¨λ‘ μ „μ—­ λ³€μˆ˜κ°€ λœλ‹€.

var x = 1; // μ „μ—­ λ³€μˆ˜ x

if(true){
    var x = 10; // μ „μ—­ λ³€μˆ˜ x (var ν‚€μ›Œλ“œ λ¬΄μ‹œλ˜κ³  μž¬ν• λ‹Ήμ΄ 이뀄진닀.)
}

console.log(x); // 10

for 문의 λ³€μˆ˜ μ„ μ–Έλ¬Έμ—μ„œ var ν‚€μ›Œλ“œλ‘œ μ„ μ–Έν•œ λ³€μˆ˜λ„ μ „μ—­ λ³€μˆ˜κ°€ λœλ‹€.

var i = 10;

for (var i = 0 ; i < 5 ; i++){
    console.log(i); // 0 1 2 3 4 
}

console.log(i); // 5

이처럼 ν•¨μˆ˜ 레벨 μŠ€μ½”ν”„λŠ” μ „μ—­ λ³€μˆ˜λ₯Ό λ‚¨λ°œν•  κ°€λŠ₯성을 높인닀. 이둜 인해 μ˜λ„μΉ˜ μ•Šκ²Œ μ „μ—­ λ³€μˆ˜κ°€ 쀑볡 μ„ μ–Έλ˜λŠ” κ²½μš°κ°€ λ°œμƒν•œλ‹€.

 

15.1.3 λ³€μˆ˜ ν˜Έμ΄μŠ€νŒ…

  var ν‚€μ›Œλ“œλ‘œ λ³€μˆ˜λ₯Ό μ„ μ–Έν•˜λ©΄ λ³€μˆ˜ ν˜Έμ΄μŠ€νŒ…μ— μ˜ν•΄ λ³€μˆ˜ 선언문이 μŠ€μ½”ν”„μ˜ μ„ λ‘λ‘œ λŒμ–΄ μ˜¬λ €μ§„ κ²ƒμ²˜λŸΌ λ™μž‘ν•œλ‹€. 즉 λ³€μˆ˜ ν˜Έμ΄μŠ€νŒ…μ— μ˜ν•΄ var ν‚€μ›Œλ“œλ‘œ μ„ μ–Έν•œ λ³€μˆ˜λŠ” λ³€μˆ˜ μ„ μ–Έλ¬Έ 이전에 μ°Έμ‘°ν•  수 μžˆλ‹€. 단 ν• λ‹Ήλ¬Έ 이전에 λ³€μˆ˜λ₯Ό μ°Έμ‘°ν•˜λ©΄ μ–Έμ œλ‚˜ undefinedλ₯Ό λ°˜ν™˜ν•œλ‹€. λ³€μˆ˜ μ„ μ–Έλ¬Έ 이전에 λ³€μˆ˜λ₯Ό μ°Έμ‘°ν•˜λŠ” 것은 λ³€μˆ˜ ν˜Έμ΄μŠ€νŒ…μ— μ˜ν•΄ μ—λŸ¬λ₯Ό λ°œμƒμ‹œν‚€μ§€λŠ” μ•Šμ§€λ§Œ ν”„λ‘œκ·Έλž¨μ˜ 흐름상 λ§žμ§€ μ•Šμ„λΏλ”λŸ¬ 가독성을 λ–¨μ–΄νŠΈλ¦¬κ³  였λ₯˜λ₯Ό λ°œμƒμ‹œν‚¬ 여지λ₯Ό 남긴닀.

console.log(foo); // undefined

foo = 1004;

console.log(foo);  // 1004

var foo;

15.2 let ν‚€μ›Œλ“œ

  var ν‚€μ›Œλ“œμ˜ 단점을 λ³΄μ™„ν•˜κΈ° μœ„ν•΄ ES6μ—μ„œλŠ” μƒˆλ‘œμš΄ λ³€μˆ˜ μ„ μ–Έ ν‚€μ›Œλ“œμΈ let ν‚€μ›Œλ“œμ™€ const ν‚€μ›Œλ“œλ₯Ό λ„μž…ν–ˆλ‹€.

 

15.2.2 λ³€μˆ˜ 쀑볡 μ„ μ–Έ κΈˆμ§€(동일 μŠ€μ½”ν”„ λ‚΄μ—μ„œ)

  var ν‚€μ›Œλ“œλ‘œ 이름이 λ™μΌν•œ λ³€μˆ˜λ₯Ό 쀑볡 μ„ μ–Έν•˜λ©΄ μ•„λ¬΄λŸ° μ—λŸ¬κ°€ λ°œμƒν•˜μ§€ μ•Šμ§€λ§Œ, let ν‚€μ›Œλ“œλ‘œ 이름이 같은 λ³€μˆ˜λ₯Ό 쀑볡 μ„ μ–Έν•˜λ©΄ 문법 μ—λŸ¬κ°€ λ°œμƒν•œλ‹€. 

 

15.2.2 블둝 레벨 μŠ€μ½”ν”„

  var ν‚€μ›Œλ“œλ‘œ μ„ μ–Έν•œ λ³€μˆ˜λŠ” μ˜€λ‘œμ§€ ν•¨μˆ˜μ˜ μ½”λ“œ λΈ”λ‘λ§Œμ„ 지역 μŠ€μ½”ν”„λ‘œ μΈμ •ν•˜λŠ” ν•¨μˆ˜ 레벨 μŠ€μ½”ν”„λ₯Ό λ”°λ₯΄μ§€λ§Œ, let ν‚€μ›Œλ“œλ‘œ μ„ μ–Έν•œ λ³€μˆ˜λŠ” λͺ¨λ“  μ½”λ“œ 블둝(ν•¨μˆ˜, ifλ¬Έ, forλ¬Έ, whileλ¬Έ, try/catchλ¬Έ λ“±)을 지역 μŠ€μ½”ν”„λ‘œ μΈμ •ν•˜λŠ” 블둝 레벨 μŠ€μ½”ν”„λ₯Ό λ”°λ₯Έλ‹€. 

let foo = 1; // μ „μ—­ λ³€μˆ˜

{
	let foo = 2; // 지역 λ³€μˆ˜
	let bar = 3; // 지역 λ³€μˆ˜
}

console.log(foo); // 1
console.log(bar); // ReferenceError λ°œμƒ

15.2.3 λ³€μˆ˜ ν˜Έμ΄μŠ€νŒ… 

  var ν‚€μ›Œλ“œλ‘œ μ„ μ–Έν•œ λ³€μˆ˜μ™€ 달리 let ν‚€μ›Œλ“œλ‘œ μ„ μ–Έν•œ λ³€μˆ˜λŠ” λ³€μˆ˜ ν˜Έμ΄μŠ€νŒ…μ΄ λ°œμƒν•˜μ§€ μ•ŠλŠ” κ²ƒμ²˜λŸΌ λ™μž‘ν•œλ‹€. 

console.log(foo); // RefrenceError λ°œμƒ
let foo;

이처럼 let ν‚€μ›Œλ“œλ‘œ μ„ μ–Έν•œ λ³€μˆ˜λ₯Ό λ³€μˆ˜ μ„ μ–Έλ¬Έ 이전에 μ°Έμ‘°ν•˜λ©΄ μ°Έμ‘° μ—λŸ¬κ°€ λ°œμƒν•œλ‹€. 이둜 인해 λ³€μˆ˜ ν˜Έμ΄μŠ€νŒ…μ΄ λ°œμƒν•˜μ§€ μ•ŠλŠ” κ²ƒμ²˜λŸΌ λ³΄μ΄λ‚˜, λ‚΄λΆ€μ μœΌλ‘œ ν˜Έμ΄μŠ€νŒ…μ€ μΌμ–΄λ‚œλ‹€. var ν‚€μ›Œλ“œλ‘œ μ„ μ–Έν•œ λ³€μˆ˜λŠ” λŸ°νƒ€μž„ 이전에 μžλ°”μŠ€ν¬λ¦½νŠΈ 엔진에 μ˜ν•΄ μ•”λ¬΅μ μœΌλ‘œ 'μ„ μ–Έ 단계'와 'μ΄ˆκΈ°ν™” 단계'κ°€ ν•œλ²ˆμ— μ§„ν–‰λœλ‹€.(4μž₯ μ°Έμ‘°) ν•˜μ§€λ§Œ, let ν‚€μ›Œλ“œλ‘œ μ„ μ–Έν•œ λ³€μˆ˜λŠ” 'μ„ μ–Έ 단계'와 'μ΄ˆκΈ°ν™” 단계'κ°€ λΆ„λ¦¬λ˜μ–΄ μ§„ν–‰λœλ‹€. 즉 λŸ°νƒ€μž„ 이전에 μžλ°”μŠ€ν¬λ¦½νŠΈ 엔진에 μ˜ν•΄ μ•”λ¬΅μ μœΌλ‘œ μ„ μ–Έ 단계가 λ¨Όμ € μ‹€ν–‰λ˜κ³ , μ΄ˆκΈ°ν™” λ‹¨κ³„λŠ” λŸ°νƒ€μž„ ν›„ λ³€μˆ˜ 선언문에 λ„λ‹¬ν–ˆμ„ λ•Œ μ‹€ν–‰λœλ‹€.

κ·Έλ ‡κΈ° λ•Œλ¬Έμ— μ΄ˆκΈ°ν™” 단계가 μ‹€ν–‰λ˜κΈ° 이전에 λ³€μˆ˜μ— μ ‘κ·Όν•˜λ €κ³  ν•˜λ©΄ μ°Έμ‘° μ—λŸ¬κ°€ λ°œμƒν•œλ‹€. μŠ€μ½”ν”„μ˜ μ‹œμž‘ 지점뢀터 μ΄ˆκΈ°ν™” μ‹œμž‘ μ§€μ κΉŒμ§€ λ³€μˆ˜λ₯Ό μ°Έμ‘°ν•  수 μ—†λŠ” ꡬ간을 μΌμ‹œμ  μ‚¬κ°μ§€λŒ€(Temporal Dead Zone)라고 λΆ€λ₯Έλ‹€.

 

<var ν‚€μ›Œλ“œ λ³€μˆ˜ μ„ μ–Έ case> μ„ μ–Έ 단계 μ΄ˆκΈ°ν™” 단계 foo === undefined
var foo; (λ³€μˆ˜ μ„ μ–Έ)  
foo = 1; (ν• λ‹Ή) ν• λ‹Ή 단계 foo === 1

 

<let ν‚€μ›Œλ“œ λ³€μˆ˜ μ„ μ–Έ case> 선언단계 foo λ³€μˆ˜ μ°Έμ‘°μ‹œ, μ°Έμ‘° μ—λŸ¬ λ°œμƒ
  μΌμ‹œμ  μ‚¬κ°μ§€λŒ€(TDZ)
let foo; (λ³€μˆ˜ μ„ μ–Έ) μ΄ˆκΈ°ν™” 단계 foo === undefined
foo = 1; (ν• λ‹Ή) ν• λ‹Ή 단계 foo === 1

μžλ°”μŠ€ν¬λ¦½νŠΈλŠ” ES6μ—μ„œ λ„μž…λœ let, constλ₯Ό ν¬ν•¨ν•΄μ„œ λͺ¨λ“  선언을 ν˜Έμ΄μŠ€νŒ…ν•œλ‹€. 단 ES6μ—μ„œ λ„μž…λœ let, const, classλ₯Ό μ‚¬μš©ν•œ 선언문은 ν˜Έμ΄μŠ€νŒ…μ΄ λ°œμƒν•˜μ§€ μ•ŠλŠ” κ²ƒμ²˜λŸΌ 보일 뿐이닀.

 

15.3 const ν‚€μ›Œλ“œ

  const ν‚€μ›Œλ“œλŠ” μƒμˆ˜λ₯Ό μ„ μ–Έν•˜κΈ° μœ„ν•΄ μ‚¬μš©ν•œλ‹€. const ν‚€μ›Œλ“œμ˜ νŠΉμ§•μ€ let ν‚€μ›Œλ“œμ™€ λŒ€λΆ€λΆ„ λ™μΌν•˜μ§€λ§Œ λͺ‡κ°€μ§€ λ‹€λ₯Έ 점듀이 μžˆλ‹€.

 

15.3.1 μ„ μ–Έκ³Ό μ΄ˆκΈ°ν™”

  const ν‚€μ›Œλ“œλ‘œ μ„ μ–Έν•œ λ³€μˆ˜λŠ” λ°˜λ“œμ‹œ μ„ μ–Έκ³Ό λ™μ‹œμ— μ΄ˆκΈ°ν™”ν•΄μ•Ό ν•œλ‹€. 그렇지 μ•ŠμœΌλ©΄ 문법 μ—λŸ¬κ°€ λ°œμƒν•œλ‹€. const ν‚€μ›Œλ“œλ‘œ μ„ μ–Έν•œ λ³€μˆ˜λŠ” let ν‚€μ›Œλ“œλ‘œ μ„ μ–Έν•œ λ³€μˆ˜μ™€ λ§ˆμ°¬κ°€μ§€λ‘œ 블둝 레벨 μŠ€μ½”ν”„λ₯Ό 가지며, λ³€μˆ˜ ν˜Έμ΄μŠ€νŒ…μ΄ λ°œμƒν•˜μ§€ μ•ŠλŠ” κ²ƒμ²˜λŸΌ λ™μž‘ν•œλ‹€.(TDZ있음)

const foo = 1; // μ„ μ–Έκ³Ό λ™μ‹œμ— μ΄ˆκΈ°ν™”
const bar; // SyntaxError λ°œμƒ

 

15.3.2 μž¬ν• λ‹Ή κΈˆμ§€

   var λ˜λŠ” let ν‚€μ›Œλ“œλ‘œ μ„ μ–Έν•œ λ³€μˆ˜λŠ” μž¬ν• λ‹Ήμ΄ μžμœ λ‘œμš°λ‚˜ const ν‚€μ›Œλ“œλ‘œ μ„ μ–Έν•œ λ³€μˆ˜λŠ” μž¬ν• λ‹Ήμ΄ κΈˆμ§€λœλ‹€.

 

15.3.3 μƒμˆ˜

  const ν‚€μ›Œλ“œλ‘œ μ„ μ–Έν•œ λ³€μˆ˜μ— μ›μ‹œ 값을 ν• λ‹Ήν•œ 경우 λ³€μˆ˜ 값을 λ³€κ²½ν•  수 μ—†λ‹€.(μž¬ν• λ‹Ήλ„ λΆˆκ°€λŠ₯ν•˜λ―€λ‘œ) μ΄λŸ¬ν•œ νŠΉμ§•μ„ μ΄μš©ν•΄ μƒμˆ˜λ₯Ό ν‘œν˜„ν•˜λŠ” 데 μ‚¬μš©ν•˜κΈ°λ„ ν•œλ‹€. λ³€μˆ˜μ˜ μƒλŒ€ κ°œλ…μΈ μƒμˆ˜λŠ” μž¬ν• λ‹Ήμ΄ κΈˆμ§€λœ λ³€μˆ˜λ₯Ό λ§ν•œλ‹€. μƒμˆ˜λŠ” μƒνƒœ μœ μ§€μ™€ 가독성, μœ μ§€λ³΄μˆ˜μ˜ 편의λ₯Ό μœ„ν•΄ 적극적으둜 μ‚¬μš©ν•΄μ•Ό ν•œλ‹€. 일반적으둜 μƒμˆ˜μ˜ 이름은 λŒ€λ¬Έμžλ‘œ μ„ μ–Έν•΄ μƒμˆ˜μž„μ„ λͺ…ν™•νžˆ λ‚˜νƒ€λ‚Έλ‹€. μ—¬λŸ¬ λ‹¨μ–΄λ‘œ 이뀄진 κ²½μš°μ—λŠ” 언더바 (_)둜 κ΅¬λΆ„ν•΄μ„œ μŠ€λ„€μ΄ν¬ μΌ€μ΄μŠ€λ‘œ ν‘œν˜„ν•˜λŠ” 것이 μΌλ°˜μ μ΄λ‹€.( 일반적으둜 μ‹λ³„μžλŠ” μΉ΄λ©œμΌ€μ΄μŠ€λ‘œ, const ν‚€μ›Œλ“œλ‘œ μ„ μ–Έν•œ μ‹λ³„μžλŠ” λŒ€λ¬Έμž + μŠ€λ„€μ΄ν¬ μΌ€μ΄μŠ€λ‘œ, μƒμ„±μž ν•¨μˆ˜λŠ” 파슀칼 μΌ€μ΄μŠ€λ‘œ ν‘œν˜„ν•˜λŠ”κ²ƒμ΄ μΌλ°˜μ μ΄λ‹€. )

 

15.3.4 const ν‚€μ›Œλ“œμ™€ 객체

  const ν‚€μ›Œλ“œλ‘œ μ„ μ–Έλœ λ³€μˆ˜μ— μ›μ‹œ 값을 ν• λ‹Ήν•œ 경우 값을 λ³€κ²½ν•  수 μ—†μ§€λ§Œ, const ν‚€μ›Œλ“œλ‘œ μ„ μ–Έλœ λ³€μˆ˜μ— 객체λ₯Ό ν• λ‹Ήν•œ 경우 값을 λ³€κ²½ν•  수 μžˆλ‹€. λ³€κ²½ κ°€λŠ₯ν•œ 값인 κ°μ²΄λŠ” μž¬ν• λ‹Ή 없이도 직접 변경이 κ°€λŠ₯ν•˜κΈ° λ•Œλ¬Έμ΄λ‹€. constν‚€μ›Œλ“œλŠ” μž¬ν• λ‹Ήμ„ κΈˆμ§€ν•  뿐 κ°’μ˜ 'λΆˆλ³€'을 μ˜λ―Έν•˜μ§€λŠ” μ•ŠλŠ”λ‹€. κ·ΈλŸ¬λ―€λ‘œ 객체의 ν”„λ‘œνΌν‹° 동적 생성, μ‚­μ œ, 갱신을 톡해 객체λ₯Ό λ³€κ²½ν•˜λŠ” 것은 κ°€λŠ₯ν•˜λ‹€. μ΄λ•Œ 객체가 λ³€κ²½λ˜λ”λΌλ„ λ³€μˆ˜μ— ν• λ‹Ήλœ μ°Έμ‘° 값은 λ³€κ²½λ˜μ§€ μ•ŠλŠ”λ‹€.

const person = {
    name : 'lee'
};

person.name = 'kim';

console.log(person.name); // kim

 

  <μœ„ λ‚΄μš©μ„ ν•˜λ‚˜μ˜ ν‘œλ‘œ 정리>

  var ν‚€μ›Œλ“œλ‘œ μ„ μ–Έλœ λ³€μˆ˜ let ν‚€μ›Œλ“œλ‘œ μ„ μ–Έλœ λ³€μˆ˜ const ν‚€μ›Œλ“œλ‘œ μ„ μ–Έλœ λ³€μˆ˜
ν˜Έμ΄μŠ€νŒ… o o (TDZ있음) o (TDZ있음)
μ „μ—­ 객체 winodw ν”„λ‘œνΌν‹° o x x
λ³€μˆ˜μ˜ 쀑볡 μ„ μ–Έ(동일 μŠ€μ½”ν”„ λ‚΄) o x x
κ°’μ˜ μž¬ν• λ‹Ή o o x