๋ณธ๋ฌธ์œผ๋กœ ๋ฐ”๋กœ๊ฐ€๊ธฐ

ํ˜ธ์ด์ŠคํŒ…(hoisting)

์ธํ„ฐํ”„๋ฆฌํ„ฐ๊ฐ€ ๋ณ€์ˆ˜์™€ ํ•จ์ˆ˜์˜ ๋ฉ”๋ชจ๋ฆฌ ๊ณต๊ฐ„์„ ์„ ์–ธ ์ „์— ๋ฏธ๋ฆฌ ํ• ๋‹นํ•˜๋Š” ๊ฒƒ์„ ์˜๋ฏธํ•œ๋‹ค. var๋กœ ์„ ์–ธํ•œ ๋ณ€์ˆ˜์˜ ๊ฒฝ์šฐ ํ˜ธ์ด์ŠคํŒ… ์‹œ undefined๋กœ ๋ณ€์ˆ˜๋ฅผ ์ดˆ๊ธฐํ™”ํ•œ๋‹ค. ๋ฐ˜๋ฉด let๊ณผ const๋กœ ์„ ์–ธํ•œ ๋ณ€์ˆ˜์˜ ๊ฒฝ์šฐ ํ˜ธ์ด์ŠคํŒ… ์‹œ ๋ณ€์ˆ˜๋ฅผ ์ดˆ๊ธฐํ™”ํ•˜์ง€ ์•Š๋Š”๋‹ค. ๋”ฐ๋ผ์„œ var๋กœ ์„ ์–ธํ•  ์‹œ ์ดˆ๊ธฐํ™” ๊ฐ’, undefined๊ฐ€ ๋‚˜์˜ค๋Š” ๊ฒƒ๊ณผ ๋‹ค๋ฅด๊ฒŒ, const์™€ let์€ ์ดˆ๊ธฐํ™” ๊ฐ’์ด ์—†๊ธฐ ๋•Œ๋ฌธ์— ์˜ค๋ฅ˜๋ฅผ ์ถœ๋ ฅํ•œ๋‹ค.

 

Temporal Dead Zone

๋ณ€์ˆ˜๊ฐ€ ํ˜„์žฌ ์Šค์ฝ”ํ”„ ๋‚ด์—์„œ ์„ ์–ธ๋์ง€๋งŒ, ์•„์ง ์ดˆ๊ธฐํ™”๋˜์ง€ ์•Š์€ ์ƒํƒœ๋ฅผ ๋งํ•œ๋‹ค. let ๋˜๋Š” const ํ‚ค์›Œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋ณ€์ˆ˜๋ฅผ ์„ ์–ธํ–ˆ์„ ๋•Œ ๋‚˜์˜ค๋Š” ๊ฐœ๋…. TDZ๋Š” ๋ณ€์ˆ˜๊ฐ€ ์„ ์–ธ๋œ ์ง€์ ๋ถ€ํ„ฐ ์ดˆ๊ธฐํ™”๋˜๊ธฐ ์ „๊นŒ์ง€, ํ•ด๋‹น ๋ณ€์ˆ˜๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์—†๊ฒŒ ํ•œ๋‹ค.

 

TDZ์— ๋น ์ง„ ์˜ˆ์‹œ

age = 20;
// Uncaught ReferenceError: Cannot access 'age' before initialization
let age;

 

๊ทธ๋Ÿผ let๊ณผ const๋Š” ํ˜ธ์ด์ŠคํŒ…๋˜์ง€ ์•Š๋Š” ๊ฒƒ์ธ๊ฐ€?

let์ด ํ˜ธ์ด์ŠคํŒ…๋˜์ง€ ์•Š๋Š” "๊ฒƒ์ฒ˜๋Ÿผ" ๋ณด์ด๋Š” ์˜ˆ์‹œ

console.log(name); 
//ReferenceError: name is not defined
const name = 'junha';

name ์„ ์–ธ ์ด์ „์— ํ˜ธ์ถœ์‹œ reference error๊ฐ€ ๋‚˜์„œ let์€ ํ˜ธ์ด์ŠคํŒ…์ด ๋˜์ง€ ์•Š๋Š”๋‹ค๊ณ  ์ƒ๊ฐํ•  ์ˆ˜ ์žˆ๋‹ค. ํ•˜์ง€๋งŒ ํ˜ธ์ด์ŠคํŒ… ๋˜์ง€ ์•Š์•„์„œ๊ฐ€ ์•„๋‹ˆ๋ผ let์˜ ๋ณ€์ˆ˜ ์ƒ์„ฑ๊ณผ์ •์ด var์™€ ๋‹ค๋ฅด๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.

 

var, let, const์˜ ๋ณ€์ˆ˜ ์ƒ์„ฑ๊ณผ์ • ๋น„๊ต

(๊ธฐ๋ณธ์ ์œผ๋กœ ๋ณ€์ˆ˜๋Š” ์„ ์–ธ-์ดˆ๊ธฐํ™”-ํ• ๋‹น์˜ 3๋‹จ๊ณ„ ์ƒ์„ฑ๊ณผ์ •์„ ๊ฐ€์ง)

  • var : ์„ ์–ธ&์ดˆ๊ธฐํ™” ๋™์‹œ์— ์ด๋ค„์ง. (์„ ์–ธ๋ถ€ & ์ดˆ๊ธฐํ™” ์„ธํŠธ๋กœ ๋‹ค๋‹˜)
  • let : ์„ ์–ธ - ์ดˆ๊ธฐํ™” ๋ถ„๋ฆฌ๋˜์–ด ์ง„ํ–‰ (์„ ์–ธ๋ถ€๋งŒ ๋‹จ๋…์œผ๋กœ ํ˜ธ์ด์ŠคํŒ…๋จ)
  • const : ์„ ์–ธ&์ดˆ๊ธฐํ™” ๋™์‹œ์— ํ•ด์•ผ ํ•จ. (์„ ์–ธ๋ถ€ & ์ดˆ๊ธฐํ™” ์„ธํŠธ๋กœ ์ •์˜ํ•ด์ค˜์•ผ ํ•˜์ง€๋งŒ ์„ธํŠธ๋กœ ํ˜ธ์ด์ŠคํŒ… ๋˜์ง„ ์•Š์Œ)

⇒ let์œผ๋กœ ์„ ์–ธํ•œ name์€ ๋งจ ์œ„๋กœ ์„ ์–ธ๋ถ€๊ฐ€ ํ˜ธ์ด์ŠคํŒ…์ด ๋˜๊ธด ๋์œผ๋‚˜, ์ดˆ๊ธฐํ™”(๋ฉ”๋ชจ๋ฆฌ ํ• ๋‹น)๊ฐ€ ์•„์ง ๋˜์ง€ ์•Š์•˜๊ธฐ ๋•Œ๋ฌธ์— reference error๊ฐ€ ๋‚˜๊ฒŒ ๋˜๋Š” ๊ฒƒ์ด๋‹ค.

age = 4;
let age;
// Cannot access 'age' before initialization

 

const์™€ let์€ ๋™์ผ ๋ณ€์ˆ˜๋ฅผ ์„ ์–ธํ•˜๋ฉด ์˜ค๋ฅ˜๋ฅผ ๋‚ ๋ฆฐ๋‹ค.

var a = 0
const b = 1;
let c = 2;

console.log(a, b); // 1,2

var a = 3
const b = 4;
let c = 5;
// Uncaught SyntaxError: Identifier 'a' has already been declared
// Uncaught SyntaxError: Identifier 'b' has already been declared

 

Block Scope

var์€ ํ•จ์ˆ˜ ์Šค์ฝ”ํ”„๋ฅผ ๊ฐ€์ง€๋ฉฐ, ๋ธ”๋ก ๋‚ด์—์„œ ์„ ์–ธํ•ด๋„ ํ•จ์ˆ˜ ์™ธ๋ถ€์—์„œ ์ ‘๊ทผ ๊ฐ€๋Šฅํ•˜๋ฉฐ ๋ณ€์ˆ˜ ์žฌํ• ๋‹น์ด ๊ฐ€๋Šฅํ•˜๋‹ค.

const๋Š” ๋ธ”๋ก ์Šค์ฝ”ํ”„๋ฅผ ๊ฐ€์ง€๋ฉฐ, ๋ธ”๋ก ์™ธ๋ถ€์—์„œ ์ ‘๊ทผํ•  ์ˆ˜ ์—†๋‹ค.

{
    var age = 20;
    const name = 'junha';
}

console.log(age); 
// 20

console.log(junha); 
// Uncaught ReferenceError: junha is not defined

 

const์™€ let์€ window์— ๋ฐ”์ธ๋”ฉ ๋˜์ง€ ์•Š๋Š”๋‹ค.

var๋กœ ์„ ์–ธํ•œ ๋ณ€์ˆ˜๋Š” window ๊ฐ์ฒด์˜ ํ”„๋กœํผํ‹ฐ์— ์ €์žฅ๋œ๋‹ค. ES5๊นŒ์ง€๋Š” ์‚ฌ์šฉ์ž๊ฐ€ ์ž„์˜๋กœ ๋งŒ๋“  ๋ณ€์ˆ˜๊ฐ€ ๋ชจ์กฐ๋ฆฌ window๋กœ ๋ฐ”์ธ๋”ฉ ๋˜๊ธฐ ๋•Œ๋ฌธ์—, window๊ฐ€ ์˜ค์—ผ์ด ๋˜๋Š” ๊ฒฝ์šฐ๊ฐ€ ๋งŽ์•˜๋‹ค. ES6๋ถ€ํ„ฐ๋Š” let, const ๋ฐ ํด๋ž˜์Šค ์‹๋ณ„์ž ๋ฐ”์ธ๋”ฉ์€ window ๊ฐ์ฒด์— ๋ฐ”์ธ๋”ฉ ๋˜์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์—, ๋”์ด์ƒ window์˜ ํ”„๋กœํผํ‹ฐ๋กœ ์ ‘๊ทผํ•  ์ˆ˜๊ฐ€ ์—†๋‹ค. ์ „์—ญ ๊ฐ์ฒด๊ฐ€ ์•„๋‹ˆ๋ผ *๋ณ„๋„์˜ ์„ ์–ธ์  ํ™˜๊ฒฝ ๋ ˆ์ฝ”๋“œ์— ๋ณด๊ด€๋œ๋‹ค. (ํฌ๋กฌ ๋””๋ฒ„๊ฑฐ๋Š” Script๋ผ๋Š” ์ด๋ฆ„์œผ๋กœ ์Šค์ฝ”ํ”„๋ฅผ ๋ถ„๋ฅ˜ํ•˜๊ณ  ์žˆ๋‹ค.)

 

* ์ „์—ญ ์‹คํ–‰์ปจํ…์ŠคํŠธ์˜ Lexical environment object์˜ environment record(=Variable Object)

 

 

๋ฐ˜์‘ํ˜•