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

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

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

var ν‚€μ›Œλ“œλ‘œ μ„ μ–Έλœ λ³€μˆ˜λŠ” 같은 μŠ€μ½”ν”„ λ‚΄μ—μ„œ 쀑볡 선언을 ν—ˆμš©ν•œλ‹€.

  1. μ΄ˆκΈ°ν™”λ¬Έμ΄ μžˆλŠ” λ³€μˆ˜ 선언문은 μžλ°”μŠ€ν¬λ¦½νŠΈ 엔진에 μ˜ν•΄ var ν‚€μ›Œλ“œκ°€ μ—†λŠ” κ²ƒμ²˜λŸΌ λ™μž‘ν•œλ‹€.

    var x = 1;
    var x = 100;
    console.log(x); // 100
  2. μ΄ˆκΈ°ν™”λ¬Έμ΄ μ—†λŠ” λ³€μˆ˜ 선언문은 λ¬΄μ‹œλœλ‹€.

    var y = 10;
    var y; // λ¬΄μ‹œλ¨
    console.log(y); // 10

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

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

var x = 1;

if (true) {
    var x = 10;
}

console.log(x); // 10

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

var ν‚€μ›Œλ“œλ‘œ λ³€μˆ˜λ₯Ό μ„ μ–Έν•˜λ©΄, λ³€μˆ˜ν˜Έμ΄μŠ€νŒ…μ— μ˜ν•΄ λ³€μˆ˜ μ„ μ–Έλ¬Έ 이전에 μ°Έμ‘°ν•  수 μžˆλ‹€.

console.log(foo); // undefined
foo = 123;
console.log(foo); // 123
var foo;

❗ λ³€μˆ˜ μ„ μ–Έλ¬Έ 이전에 λ³€μˆ˜λ₯Ό μ°Έμ‘°ν•˜λŠ” 것은 μ—λŸ¬λ₯Ό λ°œμƒμ‹œν‚€μ§€λŠ” μ•Šμ§€λ§Œ 가독성을 λ–¨μ–΄λœ¨λ¦°λ‹€λŠ” λ¬Έμ œκ°€ μžˆλ‹€

β€œ4.3 λ³€μˆ˜ 선언” μ°Έκ³ 

  • var ν‚€μ›Œλ“œλ‘œ μ„ μ–Έν•œ λ³€μˆ˜λŠ” λŸ°νƒ€μž„ 이전에 μžλ°”μŠ€ν¬λ¦½νŠΈ 엔진에 μ˜ν•΄ μ•”λ¬΅μ μœΌλ‘œ β€œμ„ μ–Έ 단계”와 β€œμ΄ˆκΈ°ν™” 단계”가 λ™μ‹œμ— μ§„ν–‰ν•œλ‹€.

  • μ„ μ–Έ λ‹¨κ³„μ—μ„œ μŠ€μ½”ν”„(μ‹€ν–‰μ»¨ν…μŠ€νŠΈμ˜ λ ‰μ‹œμ»¬ ν™˜κ²½)에 λ³€μˆ˜ μ‹λ³„μžλ₯Ό λ“±λ‘ν•˜κ³  μ¦‰μ‹œ μ΄ˆκΈ°ν™” λ‹¨κ³„μ—μ„œ undefined둜 λ³€μˆ˜λ₯Ό μ΄ˆκΈ°ν™”ν•œλ‹€.

βœ…15.2 let ν‚€μ›Œλ“œ (feat. var ν‚€μ›Œλ“œμ™€μ˜ 차이점)

let ν‚€μ›Œλ“œ λŠ” ES6 에 λ„μž…λ˜μ–΄ var ν‚€μ›Œλ“œμ˜ 단점을 λ³΄μ™„ν•˜κΈ° μœ„ν•΄ λ“±μž₯

1. λ³€μˆ˜ 쀑볡 μ„ μ–Έ κΈˆμ§€

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

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

let bar = 123;
let bar = 456; // SyntaxError: Identifier 'bar' has already been declared

2. 블둝 레벨 μŠ€μ½”ν”„

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

  • μ½”λ“œ 블둝 λ‚΄μ—μ„œ μ„ μ–Έν•œ λ³€μˆ˜λŠ” μ§€μ—­λ³€μˆ˜

let foo = 1;

{
    let foo = 2;
    let bar = 3;
}

console.log(foo); // 1
console.log(bar); // ReferenceError: bar is not defined

3. λ³€μˆ˜ ν˜Έμ΄μŠ€νŒ… *

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

console.log(foo); // ReferenceError: foo is not defined
let foo;

let ν‚€μ›Œλ“œλ‘œ μ„ μ–Έν•œ λ³€μˆ˜λŠ” β€œμ„ μ–Έ 단계”와 β€œμ΄ˆκΈ°ν™” 단계”가 λΆ„λ¦¬λ˜μ–΄ μ§„ν–‰ν•œλ‹€.

λŸ°νƒ€μž„ 이전에 μžλ°”μŠ€ν¬λ¦½νŠΈ 엔진에 μ˜ν•΄ μ•”λ¬΅μ μœΌλ‘œ 선언단계가 λ¨Όμ € μ‹€ν–‰λ˜μ§€λ§Œ, μ΄ˆκΈ°ν™” λ‹¨κ³„λŠ” λ³€μˆ˜ 선언문에 λ„λ‹¬ν–ˆμ„ λ•Œ μ‹€ν–‰λœλ‹€.

λ”°λΌμ„œ, μ΄ˆκΈ°ν™” 단계가 μ‹€ν–‰λ˜κΈ° 이전에 λ³€μˆ˜ μ ‘κ·Ό μ‹œ, μœ„ μ½”λ“œμ²˜λŸΌ μ°Έμ‘° μ—λŸ¬(Reference Error)κ°€ λ°œμƒν•œλ‹€.

μŠ€μ½”ν”„μ˜ μ‹œμž‘ 지점뢀터 μ΄ˆκΈ°ν™” 단계 μ‹œμž‘ 지점(λ³€μˆ˜ μ„ μ–Έλ¬Έ)κΉŒμ§€ λ³€μˆ˜λ₯Ό μ°Έμ‘°ν•  수 μ—†λŠ” 데, 이 ꡬ간을 μΌμ‹œμ  μ‚¬κ°μ§€λŒ€(Temporal Dead Zone; TDZ)라 λΆ€λ₯Έλ‹€.

// πŸ‘‰λŸ°νƒ€μž„ 이전 : μ„ μ–Έ 단계 μ‹œν–‰
console.log(foo); // ReferenceError: foo is not defined

let foo; // πŸ‘‰λ³€μˆ˜ μ„ μ–Έλ¬Έ : μ΄ˆκΈ°ν™” 단계 μ‹€ν–‰
console.log(foo); // undefined

foo = 1; // πŸ‘‰ν• λ‹Ήλ¬Έ : ν• λ‹Ή 단계 μ‹€ν–‰
console.log(foo); // 1

🧐 μ‹€μ œλ‘œ λ³€μˆ˜ ν˜Έμ΄μŠ€νŒ…μ„ λ°œμƒν•˜μ§€ μ•ŠλŠ” 것은 μ•„λ‹Œκ°€?

No. λ³€μˆ˜ ν˜Έμ΄μŠ€νŒ…μ€ λ°œμƒν•œλ‹€!

let foo = 1; // μ „μ—­ λ³€μˆ˜
{
    console.log(foo); // ReferenceError: Cannot access 'foo' before initialization
    let foo = 2;
}

λ§Œμ•½, λ³€μˆ˜ ν˜Έμ΄μŠ€νŒ…μ΄ λ°œμƒν•˜μ§€ μ•ŠλŠ”λ‹€λ©΄, μœ„ μ½”λ“œλŠ” μ „μ—­λ³€μˆ˜μ˜ 값을 좜λ ₯ν•΄μ•Ό ν•œλ‹€. ν•˜μ§€λ§Œ μ°Έμ‘° μ—λŸ¬κ°€ λ°œμƒν•˜λ―€λ‘œ, λ³€μˆ˜ ν˜Έμ΄μŠ€νŒ…μ€ λ™μž‘ν•˜λŠ” 것을 확인할 수 μžˆλ‹€.

μ°Έκ³  ) μ „μ—­ 객체와 let

var ν‚€μ›Œλ“œλ‘œ μ„ μ–Έν•œ μ „μ—­ λ³€μˆ˜μ™€ μ „μ—­ ν•¨μˆ˜, 그리고 μ„ μ–Έν•˜μ§€ μ•Šμ€ λ³€μˆ˜μ— 값을 ν• λ‹Ήν•œ 암묡적 전역은 μ „μ—­ 객체 window의 ν”„λ‘œνΌν‹°κ°€ λœλ‹€.

ν•˜μ§€λ§Œ, let ν‚€μ›Œλ“œλ‘œ μ„ μ–Έν•œ μ „μ—­ λ³€μˆ˜λŠ” μ „μ—­ 객체의 ν”„λ‘œνΌν‹°κ°€ μ•„λ‹ˆκΈ° λ•Œλ¬Έμ— window.foo와 같이 μ ‘κ·Όν•  수 μ—†λ‹€.

let μ „μ—­ λ³€μˆ˜λŠ” 보이지 μ•ŠλŠ” κ°œλ…μ μΈ 블둝(μ „μ—­ λ ‰μ‹œμ»¬ ν™˜κ²½μ˜ 선언적 ν™˜κ²½ λ ˆμ½”λ“œ(DER)) 내에 μ‘΄μž¬ν•œλ‹€.

// λΈŒλΌμš°μ € ν™˜κ²½ κ°€μ •
let x = 1;

console.log(window.x); // undefined
console.log(x); // 1

βœ…15.3 const ν‚€μ›Œλ“œ

const ν‚€μ›Œλ“œλŠ” μƒμˆ˜(constant)λ₯Ό μ„ μ–Έν•˜κΈ° μœ„ν•΄ μ‚¬μš©ν•œλ‹€. (항상 X)

일반적으둜 let ν‚€μ›Œλ“œμ™€ λŒ€λΆ€λΆ„ μ„±μ§ˆμ΄ λ™μΌν•˜κΈ° λ•Œλ¬Έμ—, let ν‚€μ›Œλ“œμ™€μ˜ 차이점만 확인

1. μ„ μ–Έκ³Ό λ™μ‹œμ— μ΄ˆκΈ°ν™”

const ν‚€μ›Œλ“œλ‘œ μ„ μ–Έν•œ λ³€μˆ˜λŠ” λ°˜λ“œμ‹œ μ„ μ–Έκ³Ό λ™μ‹œμ— μ΄ˆκΈ°ν™”λ₯Ό ν•΄μ•Όν•œλ‹€.

const foo; // SyntaxError: Missing initializer in const declaration

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

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

const foo = 1;
foo = 2; // TypeError: Assignment to constant variable.

3. μƒμˆ˜

const ν‚€μ›Œλ“œλ‘œ μ„ μ–Έν•œ λ³€μˆ˜μ— μ›μ‹œ 값을 ν• λ‹Ήν•˜λ©΄, 값을 λ³€κ²½ν•  수 μ—†λ‹€.

🧐 μƒμˆ˜λž€?

  • μž¬ν• λ‹Ήμ΄ κΈˆμ§€λœ λ³€μˆ˜λ‘œ, μƒμˆ˜λ„ λ³€μˆ˜μ²˜λŸΌ 값을 μ €μž₯ν•˜κΈ° μœ„ν•œ λ©”λͺ¨λ¦¬ 곡간을 κ°€μ§„λ‹€.

  • λ³€μˆ˜λŠ” μ–Έμ œλ“ μ§€ μž¬ν• λ‹Ήμ„ 톡해 값을 λ³€κ²½ν•  수 μžˆμ§€λ§Œ, μƒμˆ˜λŠ” μž¬ν• λ‹Ήμ΄ κΈˆμ§€λ  뿐이닀.

  • μƒνƒœ μœ μ§€μ™€ 가독성, μœ μ§€λ³΄μˆ˜μ˜ 편의λ₯Ό μœ„ν•΄ μƒμˆ˜ μ‚¬μš©μ΄ ꢌμž₯λœλ‹€.

  • 일반적으둜 μƒμˆ˜ 이름은 λŒ€λ¬Έμžλ‘œ μ„ μ–Έν•˜κ³ , μ—¬λŸ¬ λ‹¨μ–΄λ‘œ 이뀄진 경우 μ–Έλ”μŠ€μ½”μ–΄(_)둜 κ΅¬λΆ„ν•˜μ—¬ μŠ€λ„€μ΄ν¬ μΌ€μ΄μŠ€λ‘œ ν‘œν˜„ν•œλ‹€.

4. 객체

const ν‚€μ›Œλ“œλ‘œ μ„ μ–Έν•œ λ³€μˆ˜μ— 객체λ₯Ό ν• λ‹Ήν•˜λ©΄, 값을 λ³€κ²½ν•  수 μžˆλ‹€.

λ³€κ²½ λΆˆκ°€λŠ₯ν•œ 값인 μ›μ‹œ 값은 μž¬ν• λ‹Ή μ—†μ΄λŠ” λ³€κ²½ν•  수 μžˆλŠ” 방법이 μ—†μ§€λ§Œ, λ³€κ²½ κ°€λŠ₯ν•œ 값인 κ°μ²΄λŠ” μž¬ν• λ‹Ή 없이도 직접 변경이 κ°€λŠ₯ν•˜κΈ° λ•Œλ¬Έμ΄λ‹€.

λ”°λΌμ„œ,,❗const ν‚€μ›Œλ“œλŠ” μž¬ν• λ‹Ήμ„ κΈˆμ§€ν•  뿐, β€œλΆˆλ³€β€μ„ μ˜λ―Έν•˜μ§€ μ•ŠλŠ”λ‹€λŠ” 것을 μ£Όμ˜ν•˜μž!

μƒˆλ‘œμš΄ 값을 ν• λ‹Ήν•˜λŠ” 것(μž¬ν• λ‹Ή)은 λΆˆκ°€λŠ₯ν•˜μ§€λ§Œ,

ν”„λ‘œνΌν‹° 동적 생성/μ‚­μ œ/κ°’ 변경을 톡해 객체λ₯Ό λ³€κ²½ν•˜λŠ” 것은 κ°€λŠ₯ν•˜λ‹€! (λ³€μˆ˜μ— ν• λ‹Ήλœ μ°Έμ‘° 값은 λ³€κ²½λ˜μ§€ μ•ŠμŒ)

Last updated