** πŸ“Œ1. λ³€μˆ˜λž€ 무엇인가?**

ν”„λ‘œκ·Έλž¨μ—μ„œ 데이터λ₯Ό μ €μž₯ν•  수 μžˆλŠ” 곡간(이름)

μ‰½κ²Œ 말해, 값을 λ‹΄λŠ” μƒμž 🎁


🏷️ 2. λ³€μˆ˜ μ„ μ–Έ ν‚€μ›Œλ“œ 비ꡐ

ν‚€μ›Œλ“œ μŠ€μ½”ν”„ ν˜Έμ΄μŠ€νŒ… TDZ μž¬μ„ μ–Έ μž¬ν• λ‹Ή νŠΉμ§•
var ν•¨μˆ˜ O (μ΄ˆκΈ°ν™”: undefined) X O O 였래된 방식, ꢌμž₯ X
let 블둝 O (μ΄ˆκΈ°ν™” X) O X O ν˜„λŒ€ ν‘œμ€€
const 블둝 O (μ΄ˆκΈ°ν™” X) O X X μƒμˆ˜, 단 객체/λ°°μ—΄ λ‚΄λΆ€ μˆ˜μ • κ°€λŠ₯

🎯 3. μŠ€μ½”ν”„(Scope) 심화

🚩 μ’…λ₯˜

μ’…λ₯˜ μ„€λͺ… λΉ„μœ 
μ „μ—­ μŠ€μ½”ν”„ μ–΄λ””μ„œλ“  μ ‘κ·Ό κ°€λŠ₯ β€œκ±΄λ¬Ό 전체에 μžˆλŠ” CCTV”
ν•¨μˆ˜ μŠ€μ½”ν”„ ν•¨μˆ˜ λ‚΄μ—μ„œλ§Œ 유효 (var) β€œλ°© μ•ˆμ—μ„œλ§Œ μΌœμ§€λŠ” 전등”
블둝 μŠ€μ½”ν”„ {} 블둝 λ‚΄ 유효 (let, const) β€œμΉΈλ§‰μ΄λ‘œ κ΅¬λΆ„λœ 곡간”

πŸ’‘ μŠ€μ½”ν”„ 예제

function test() {
  if (true) {
    var x = 1;
    let y = 2;
    const z = 3;
  }
  console.log(x); // 1 (var β†’ ν•¨μˆ˜ μŠ€μ½”ν”„)
  console.log(y); // ReferenceError (let β†’ 블둝 μŠ€μ½”ν”„)
  console.log(z); // ReferenceError (const β†’ 블둝 μŠ€μ½”ν”„)
}
test();

πŸš€ 4. ν˜Έμ΄μŠ€νŒ…(λŒμ–΄μ˜¬λ¦Ό) 심화

πŸ”₯ μ •μ˜:

λ³€μˆ˜μ™€ ν•¨μˆ˜ 선언이 ν•΄λ‹Ή μŠ€μ½”ν”„μ˜ μ΅œμƒλ‹¨μœΌλ‘œ λŒμ–΄μ˜¬λ €μ§€λŠ” ν˜„μƒ


πŸ“Œ 핡심 차이

ν‚€μ›Œλ“œ ν˜Έμ΄μŠ€νŒ… μ΄ˆκΈ°ν™”
var O undefined
let, const O μ΄ˆκΈ°ν™” X β†’ TDZ λ°œμƒ

🧩 ν˜Έμ΄μŠ€νŒ… 심화 μ˜ˆμ‹œ

console.log(a); // undefined (var)
var a = 10;
console.log(b); // ReferenceError (let)
let b = 20;

πŸ“Š λ‚΄λΆ€ λ™μž‘:

1. var a β†’ λ©”λͺ¨λ¦¬ 곡간 확보 β†’ undefined
2. let b β†’ λ©”λͺ¨λ¦¬ 곡간 확보 β†’ μ΄ˆκΈ°ν™” μ „ μ ‘κ·Ό κΈˆμ§€ (TDZ)

πŸ•΅οΈ 5. TDZ (Temporal Dead Zone) μ™„μ „ 이해

μš©μ–΄ μ„€λͺ…
TDZ let/constκ°€ μ„ μ–Έλœ λΈ”λ‘μ˜ μ‹œμž‘ ~ μ΄ˆκΈ°ν™” μ „κΉŒμ§€ μ ‘κ·Ό λΆˆκ°€
이유 λ³€μˆ˜μ˜ β€œμ•ˆμ •μ„±β€ 보μž₯ (μ΄ˆκΈ°ν™” μ•ˆ 된 κ°’ μ°Έμ‘° λ°©μ§€)

πŸ“Œ TDZ 심화 μ˜ˆμ‹œ

{
  // TDZ μ‹œμž‘
  console.log(myVar); // ❌ ReferenceError
  let myVar = 100;
  // TDZ 끝 (μ΄ˆκΈ°ν™” ν›„ μ ‘κ·Ό κ°€λŠ₯)
}

πŸ” λΉ„μœ :

TDZ = μ˜ˆμ•½ μ‹œμž‘ μ „ μž…μž₯ λΆˆκ°€ν•œ 곡연μž₯ 🎭

var: μ˜ˆμ•½ 없어도 무쑰건 μž…μž₯

let/const: μ˜ˆμ•½ μ‹œκ°„ μ΄ν›„μ—λ§Œ μž…μž₯ κ°€λŠ₯, μ „μ—” 무쑰건 μ—λŸ¬


πŸ† 6. μž¬μ„ μ–Έ & μž¬ν• λ‹Ή

ν‚€μ›Œλ“œ μž¬μ„ μ–Έ μž¬ν• λ‹Ή 주의
var O O μ—¬λŸ¬ 번 μ„ μ–Έ κ°€λŠ₯ (ν˜Όλž€)
let X O λ³€μˆ˜ κ°’ λ³€κ²½ κ°€λŠ₯
const X X (바인딩 λΆˆλ³€) 단, 객체 λ‚΄λΆ€ 속성은 λ³€κ²½ κ°€λŠ₯

πŸ“Œ const 객체 λ‚΄λΆ€ 속성 λ³€κ²½ μ˜ˆμ‹œ

const obj = { name: "JS" };
obj.name = "JavaScript"; // κ°€λŠ₯

const arr = [1, 2];
arr.push(3); // κ°€λŠ₯

πŸ“’ ν—·κ°ˆλ¦¬λŠ” 포인트!

constλŠ” λ³€μˆ˜ 바인딩 λΆˆλ³€

객체 자체의 μ°Έμ‘° 값은 μœ μ§€, λ‚΄λΆ€ ν”„λ‘œνΌν‹°λŠ” λ³€κ²½ κ°€λŠ₯!


πŸ’₯ 7. μ‹€λ¬΄μ—μ„œ λ°œμƒν•˜λŠ” λ³€μˆ˜ κ΄€λ ¨ 트랩 μ˜ˆμ‹œ


πŸ”₯ ν΄λ‘œμ € + 루프 문제

for (var i = 0; i < 3; i++) {
  setTimeout(() => console.log(i), 1000);
}
// 좜λ ₯: 3, 3, 3 (λͺ¨λ‘ 3)

원인:

βœ… ν•΄κ²°: let μ‚¬μš©

for (let i = 0; i < 3; i++) {
  setTimeout(() => console.log(i), 1000);
}
// 좜λ ₯: 0, 1, 2 (블둝 μŠ€μ½”ν”„)

⚠️ μž¬μ„ μ–Έ ν˜Όλž€ μ˜ˆμ‹œ

var x = 10;
var x = 20; // κ°€λŠ₯ (ν˜Όλž€ 유발)

let y = 10;
let y = 20; // SyntaxError

πŸŽ“ 8. 기술 λ©΄μ ‘ λŒ€λΉ„ 질문

질문 λ‹΅λ³€ 포인트
var, let, const 차이점? μŠ€μ½”ν”„, ν˜Έμ΄μŠ€νŒ…, TDZ, μž¬μ„ μ–Έ/μž¬ν• λ‹Ή 차이 ꡬ체적으둜
TDZλž€? μ΄ˆκΈ°ν™” μ „ μ ‘κ·Ό κΈˆμ§€, ReferenceError λ°œμƒ
const의 객체 λ‚΄λΆ€ 속성 λ³€κ²½ κ°€λŠ₯? O (바인딩 λΆˆλ³€, λ‚΄λΆ€ κ°€λ³€μ„± ν—ˆμš©)
var μ‚¬μš© μ‹œ λ°œμƒν•  문제점? ν•¨μˆ˜ μŠ€μ½”ν”„ β†’ μ˜λ„μΉ˜ μ•Šμ€ κ°’ 곡유, μž¬μ„ μ–Έ ν˜Όλž€
ν΄λ‘œμ € + λ£¨ν”„μ—μ„œ varκ³Ό let 차이? let β†’ 블둝 μŠ€μ½”ν”„, var β†’ ν•¨μˆ˜ μŠ€μ½”ν”„ (κ°’ 곡유 문제 λ°œμƒ)

πŸ“ 9. λ…Έμ…˜μš© 깔끔 ν‘œ μš”μ•½


🚩 λ³€μˆ˜ ν‚€μ›Œλ“œ 비ꡐ

ν‚€μ›Œλ“œ μŠ€μ½”ν”„ ν˜Έμ΄μŠ€νŒ… TDZ μž¬μ„ μ–Έ μž¬ν• λ‹Ή νŠΉμ§•
var ν•¨μˆ˜ O (undefined) X O O 였래된 방식, ꢌμž₯ X
let 블둝 O (μ΄ˆκΈ°ν™” X) O X O ν˜„λŒ€ κΈ°λ³Έ
const 블둝 O (μ΄ˆκΈ°ν™” X) O X X μƒμˆ˜, λ‚΄λΆ€ μˆ˜μ • κ°€λŠ₯

πŸ“š 10. λ©”λͺ¨λ¦¬ λ‚΄λΆ€ λ™μž‘κΉŒμ§€ 심화 정리

단계 λ™μž‘
μ„ μ–Έ λ©”λͺ¨λ¦¬ 곡간 확보
var μ΄ˆκΈ°ν™”: undefined
let, const TDZ μƒνƒœ β†’ μ΄ˆκΈ°ν™” μ „ μ ‘κ·Ό μ‹œ μ—λŸ¬
ν• λ‹Ή μ‹€μ œ κ°’ μ €μž₯

🌟 1️⃣ μžλ°”μŠ€ν¬λ¦½νŠΈ μžλ£Œν˜•μ΄λž€?

κ°’μ˜ μ’…λ₯˜μ™€ μ„±μ§ˆμ„ μ •μ˜ν•˜λŠ” 것!

μžλ°”μŠ€ν¬λ¦½νŠΈ νŠΉμ§•:


πŸ“Œ 2️⃣ μžλ£Œν˜•μ˜ 2λŒ€ λΆ„λ₯˜

ꡬ뢄 μ’…λ₯˜ μ €μž₯ μœ„μΉ˜ 볡사 방식 λΆˆλ³€μ„±
μ›μ‹œ νƒ€μž… (Primitive) Number, String, Boolean, undefined, null, Symbol, BigInt Stack κ°’ 볡사 (κΉŠμ€ 볡사) Immutable (λΆˆλ³€)
μ°Έμ‘° νƒ€μž… (Reference) Object, Array, Function, Date, RegExp λ“± Heap (μ£Όμ†Œ), Stack (μ£Όμ†Œ μ €μž₯) μ°Έμ‘° 볡사 (얕은 볡사) Mutable (κ°€λ³€)

πŸ”₯ 3️⃣ μ›μ‹œ νƒ€μž…(Primitive Types) μ™„μ „ 심화


πŸ”’ (1) Number

let int = 42;
let float = 3.14;
console.log(1 / 0); // Infinity
console.log('abc' * 2); // NaN

πŸ“Œ λΆ€λ™μ†Œμˆ˜μ  였차 심화:

console.log(0.1 + 0.2); // 0.30000000000000004

βœ… ν•΄κ²°: Number.EPSILON, λ˜λŠ” μ •μˆ˜λ‘œ λ³€ν™˜ ν›„ 계산


πŸ”€ (2) String

let str = 'JS';
str[0] = 'A';
console.log(str); // 'JS'

πŸ“Œ ν…œν”Œλ¦Ώ λ¦¬ν„°λŸ΄ (ES6+)

let name = 'JavaScript';
console.log(`Hello, ${name}`);

πŸ”₯ (3) Boolean

javascript
λ³΅μ‚¬νŽΈμ§‘
let isDone = true;
let isFalse = false;

πŸ“Œ Truthy / Falsy 심화:

Falsy κ°’


false

,

0

,

""

,

null

,

undefined

,

NaN

if (0) console.log('Falsy'); // μ‹€ν–‰ μ•ˆ 됨

πŸ•³οΈ (4) undefined

let a;
console.log(a); // undefined

πŸŒ‘ (5) null

let b = null;

πŸ“Œ λ©΄μ ‘ 단골:

console.log(typeof null); // 'object' β†’ JS 초창기 버그

πŸŒ€ (6) Symbol (ES6)

let id1 = Symbol('id');
let id2 = Symbol('id');
console.log(id1 === id2); // false

βœ… 싀무: 객체 ν”„λ‘œνΌν‹°μ˜ 고유 ν‚€λ‘œ ν™œμš©


πŸ”’ (7) BigInt (ES2020)

let big = 123456789012345678901234567890n;
console.log(big * 2n);

πŸ“Œ μš©λ„: 2^53-1 초과 큰 μ •μˆ˜ 처리



πŸ—οΈ 4️⃣ μ°Έμ‘° νƒ€μž…(Reference Types) 심화


μ’…λ₯˜ νŠΉμ§• μ˜ˆμ‹œ
Object ν‚€-κ°’ 쌍 {name: 'JS'}
Array μˆœμ„œ μžˆλŠ” κ°’ 리슀트 [1,2,3]
Function μ‹€ν–‰ κ°€λŠ₯ν•œ 객체 function() {}
Date, RegExp λ“± λ‚΄μž₯ 객체 Β 

πŸ” μ°Έμ‘° νƒ€μž… νŠΉμ§•

νŠΉμ„± μ„€λͺ…
Heap μ €μž₯ μ‹€μ œ 값은 Heap, Stackμ—λŠ” μ£Όμ†Œ
얕은 볡사 μ°Έμ‘° κ°’λ§Œ 볡사, 원본 영ν–₯
Mutable λ‚΄λΆ€ κ°’ 자유둭게 λ³€κ²½ κ°€λŠ₯

πŸ“Œ 얕은 볡사 문제 심화

let obj1 = {name: 'JS'};
let obj2 = obj1;
obj2.name = 'Changed';
console.log(obj1.name); // 'Changed'

βœ… κΉŠμ€ 볡사 (Deep Copy)

let obj3 = structuredClone(obj1);

πŸ“Œ μ‹€λ¬΄μ—μ„œλŠ” lodash cloneDeep()도 μ‚¬μš©


πŸ”₯ 5️⃣ λΆˆλ³€μ„±(Immutable) vs κ°€λ³€μ„±(Mutable)

νƒ€μž… λΆˆλ³€μ„± μ—¬λΆ€ μˆ˜μ • μ‹œ λ™μž‘
μ›μ‹œ νƒ€μž… λΆˆλ³€ μƒˆ κ°’ 생성, κΈ°μ‘΄ λ³€κ²½ λΆˆκ°€
μ°Έμ‘° νƒ€μž… κ°€λ³€ 원본 λ‚΄λΆ€ 속성 λ³€κ²½ κ°€λŠ₯

λ©”λͺ¨λ¦¬ ꡬ쑰 μ‹œκ°ν™”

Primitive:
[ Stack ] β†’ κ°’ 자체 μ €μž₯

Reference:
[ Stack ] β†’ μ£Όμ†Œ β†’ [ Heap ] μ‹€μ œ 데이터

🎯 6️⃣ 싀무 & λ©΄μ ‘ ν•„μ‚΄ 포인트


질문 핡심
μ›μ‹œ & μ°Έμ‘° νƒ€μž… 차이? Stack vs Heap, λΆˆλ³€ vs κ°€λ³€, 볡사 차이
typeof null κ²°κ³Ό? β€œobject”, JS 초기 버그
얕은 볡사와 κΉŠμ€ 볡사 차이? μ£Όμ†Œ 곡유 μ—¬λΆ€
Truthy/Falsy κ°’ ꡬ뢄? μ‹€λ¬΄μ—μ„œ 쑰건문 주의 ν•„μˆ˜
λΆˆλ³€μ„± μœ μ§€ μ™œ μ€‘μš”ν•œκ°€? μƒνƒœ 예츑 κ°€λŠ₯, Redux λ“±μ—μ„œ 핡심

πŸ“ 7️⃣ 깔끔 정리


πŸ“‹ μžλ£Œν˜• μ •λ¦¬ν‘œ

λΆ„λ₯˜ νƒ€μž… λΆˆλ³€μ„± μ €μž₯ μœ„μΉ˜ 볡사
μ›μ‹œ νƒ€μž… Number, String, Boolean, undefined, null, Symbol, BigInt λΆˆλ³€ Stack κ°’ 볡사
μ°Έμ‘° νƒ€μž… Object, Array, Function λ“± κ°€λ³€ Heap(κ°’), Stack(μ°Έμ‘°) 얕은 볡사

πŸ“ 마무리 μ½”λ“œ 예제

<!DOCTYPE html>
<html lang="ko">

<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>

    <script>
        /*
        πŸ“Œ 1. κΈ°λ³Έ μžλ£Œν˜• (Primitive Type)
        1) number : μ •μˆ˜, μ‹€μˆ˜ ꡬ뢄이 μ—†λ‹€
                    NaN (Not a Number) : μˆ«μžκ°€ μ•„λ‹˜
                    Infinity/-Infinity: +0/-0으둜 λ‚˜λˆˆ κ°’. 뢈λŠ₯ κ°’.
        2) string : 문자/λ¬Έμžμ—΄ ꡬ뢄이 μ—†λ‹€. μž‘μ€λ”°μ˜΄ν‘œ(''), ν°λ”°μ˜΄ν‘œ("") λͺ¨λ‘ μ‚¬μš© κ°€λŠ₯
        3) boolean : true/false
        4) null : 값이 "μ—†μŒ" (μ˜λ„μ μœΌλ‘œ λΉ„μ›Œλ‘ )
        5) undefined : 값이 μ €μž₯된 적이 μ—†λ‹€. μ΄ˆκΈ°ν™”λ˜μ§€ μ•Šμ€ μƒνƒœμ˜ λ³€μˆ˜μž„
        6) symbol (ES6) : μœ μΌν•œ κ°’ (μ‹¬λ³Όν˜•)
        7) bigint (ES11) : μ•„μ£Ό 큰 μ •μˆ˜
        */

        console.log("πŸ“Œ number νƒ€μž… μ˜ˆμ‹œ");
        let num = 123;
        console.log(num, typeof num); // 123 'number'

        let float = 3.14;
        console.log(float, typeof float); // 3.14 'number'

        // NaN (μˆ«μžν˜•μΈλ° 'μˆ«μžκ°€ μ•„λ‹˜'❌)
        let invalidNum = 100 / "사과";
        console.log(invalidNum, typeof invalidNum); // NaN 'number'

        // Infinity / -Infinity
        console.log(1 / 0);  // Infinity
        console.log(-1 / 0); // -Infinity

        console.log("\nπŸ“Œ string νƒ€μž… μ˜ˆμ‹œ");
        let str1 = 'hello';
        let str2 = "world";
        console.log(str1, typeof str1); // hello 'string'
        console.log(str2, typeof str2); // world 'string'

        console.log("\nπŸ“Œ boolean νƒ€μž… μ˜ˆμ‹œ");
        let isTrue = true;
        let isFalse = false;
        console.log(isTrue, typeof isTrue);   // true 'boolean'
        console.log(isFalse, typeof isFalse); // false 'boolean'

        console.log("\nπŸ“Œ nullκ³Ό undefined 차이");
        let empty = null;
        let notAssigned;
        console.log(empty, typeof empty);       // null 'object' (μžλ°”μŠ€ν¬λ¦½νŠΈμ˜ 였래된 섀계 버그 🀯)
        console.log(notAssigned, typeof notAssigned); // undefined 'undefined'

        // 심볼, λΉ…μΈνŠΈ 심화 μ˜ˆμ‹œ
        console.log("\nπŸ“Œ symbol, bigint μ˜ˆμ‹œ (심화)");
        let sym = Symbol('unique');
        console.log(sym, typeof sym); // Symbol(unique) 'symbol'

        let big = 1234567890123456789012345678901234567890n;
        console.log(big, typeof big); // 'bigint'
    </script>

    <script>
        /*
        πŸ“Œ 2. μžλ°”μŠ€ν¬λ¦½νŠΈ λ³€μˆ˜μ˜ νŠΉμ§•
        1) 동적 νƒ€μž… (Dynamically Typed) - μ„ μ–Έν•˜μ§€ μ•Šμ•„λ„ λ³€μˆ˜ μ‚¬μš© κ°€λŠ₯ (❌ μΆ”μ²œX, 암묡적 μ „μ—­λ³€μˆ˜λ¨)
        2) λ³€μˆ˜ μ„ μ–Έμ‹œ μžλ£Œν˜• μž‘μ„±ν•˜μ§€ μ•ŠλŠ”λ‹€
        3) λ³€μˆ˜μ— μ €μž₯된 값에 따라 μžλ£Œν˜• 결정됨 => 값이 μˆ˜μ •λ˜λ©΄ μžλ£Œν˜• λ³€κ²½ κ°€λŠ₯
        */

        // var ν‚€μ›Œλ“œ μ‚¬μš© μ˜ˆμ‹œ
        var a; // μ„ μ–Έ (μ΄ˆκΈ°ν™” X)
        console.log(a); // undefined

        var a; // 같은 μ΄λ¦„μœΌλ‘œ μž¬μ„ μ–Έ κ°€λŠ₯ (var의 νŠΉμ§•!)
        a = 10;
        console.log(a, typeof a); // 10 'number'

        // κ°’ λ³€κ²½ β†’ μžλ£Œν˜• λ³€κ²½
        a = "Hello world";
        console.log(a, typeof a); // Hello world 'string'

        // λ³€μˆ˜ μ„ μ–Έ 없이 μ‚¬μš© (❌ 암묡적 μ „μ—­ λ³€μˆ˜)
        b = false;
        console.log(b, typeof b); // false 'boolean'

        /*
        ⚠️ **μ€‘μš”**: μžλ°”μŠ€ν¬λ¦½νŠΈλŠ” "동적 νƒ€μž… μ–Έμ–΄"
        λ³€μˆ˜μ˜ μžλ£Œν˜•μ΄ 값에 따라 λ°”λ€Œλ―€λ‘œ μ‹€μˆ˜ν•  κ°€λŠ₯성이 큼!
        */
    </script>

    <script>
        /*
        πŸ“Œ 3. λ³€μˆ˜ μ„ μ–Έ ν‚€μ›Œλ“œ
        
        1) var
            (1) λ²”μœ„ : ν•¨μˆ˜ 레벨 (function scope)
            (2) λ³€μˆ˜ μ„ μ–Έ μƒλž΅ κ°€λŠ₯ (❌ ꢌμž₯ν•˜μ§€ μ•ŠμŒ)
            (3) 같은 λ³€μˆ˜λͺ…μœΌλ‘œ μž¬μ„ μ–Έ κ°€λŠ₯
            (4) μ΄ˆκΈ°ν™” μƒλž΅ κ°€λŠ₯ (undefined)
        
        2) let (ES6)
            (1) λ²”μœ„ : 블둝 레벨 {} (μ§€μ—­ λ³€μˆ˜)
            (2) λ³€μˆ˜ μ„ μ–Έ μƒλž΅ ❌ λΆˆκ°€λŠ₯ (무쑰건 let)
            (3) 같은 λ³€μˆ˜λͺ… μž¬μ„ μ–Έ λΆˆκ°€λŠ₯
            (4) μ΄ˆκΈ°ν™” μƒλž΅ κ°€λŠ₯ (μ„ μ–Έ ν›„ undefined μƒνƒœ, but TDZ 쑴재)
        
        3) const (ES6)
            (1) λ²”μœ„ : 블둝 레벨 {}
            (2) μ„ μ–Έ μƒλž΅ ❌ λΆˆκ°€λŠ₯
            (3) 같은 λ³€μˆ˜λͺ… μž¬μ„ μ–Έ λΆˆκ°€λŠ₯
            (4) μ΄ˆκΈ°ν™” μƒλž΅ ❌ λΆˆκ°€λŠ₯ (μ„ μ–Έκ³Ό λ™μ‹œμ— μ΄ˆκΈ°ν™” ν•„μˆ˜)
            (5) κ°’ λ³€κ²½ λΆˆκ°€λŠ₯ (μƒμˆ˜)
        
        πŸ’‘ const κ°μ²΄λ‚˜ λ°°μ—΄μ˜ 경우 λ‚΄λΆ€ 값은 λ³€κ²½ κ°€λŠ₯!
        */

        console.log("\nπŸ“Œ let μ˜ˆμ‹œ");
        let user = "user1";
        console.log(user, typeof user); // user1 'string'
        // let user = "user2"; // ❌ 쀑볡 μ„ μ–Έ λΆˆκ°€

        console.log("\nπŸ“Œ const μ˜ˆμ‹œ");
        const pw = "pw1";
        console.log(pw, typeof pw); // pw1 'string'
        // pw = "pw2"; // ❌ κ°’ λ³€κ²½ λΆˆκ°€

        // 심화 const 객체 μ˜ˆμ‹œ
        const person = { name: "철수" };
        person.name = "영희"; // λ‚΄λΆ€ 값은 λ³€κ²½ κ°€λŠ₯!
        console.log(person);

        // const λ°°μ—΄ μ˜ˆμ‹œ
        const arr = [1, 2, 3];
        arr.push(4);
        console.log(arr); // [1, 2, 3, 4]

    </script>

    <script>
        /*
        πŸ“Œ 4. ν˜Έμ΄μŠ€νŒ… (Hoisting)
        
        μžλ°”μŠ€ν¬λ¦½νŠΈλŠ” μ½”λ“œ μ‹€ν–‰ μ „, "λ³€μˆ˜ μ„ μ–Έ"κ³Ό "ν•¨μˆ˜ μ„ μ–Έ"을 μ½”λ“œ μ΅œμƒλ‹¨μœΌλ‘œ λŒμ–΄μ˜¬λ¦Ό!
        
        1) varλŠ” μ„ μ–Έλ§Œ λŒμ–΄μ˜¬λ €μ§€κ³  μ΄ˆκΈ°ν™”λŠ” μ•ˆ 됨 (undefined)
        2) let, constλŠ” ν˜Έμ΄μŠ€νŒ… λ˜μ§€λ§Œ TDZ(Temporal Dead Zone)에 빠짐 β†’ μ΄ˆκΈ°ν™” μ „ μ ‘κ·Ό μ‹œ μ—λŸ¬
        */

        console.log("\nπŸ“Œ var ν˜Έμ΄μŠ€νŒ… μ˜ˆμ‹œ");
        console.log(c); // undefined (선언은 올라감)
        var c;
        c = Math.sqrt(25); // Math λŒ€μ†Œλ¬Έμž μˆ˜μ •!
        console.log(c, typeof c); // 5 'number'

        // console.log(userLet); // ❌ ReferenceError
        // let userLet = "ν˜Έμ΄μŠ€νŒ… ν…ŒμŠ€νŠΈ";

        /*
        βœ… 심화 κ°œλ…: TDZ
        let, const둜 μ„ μ–Έλœ λ³€μˆ˜λŠ” μ„ μ–Έ μ „ μ ‘κ·Ό μ‹œ μ—λŸ¬ λ°œμƒ (μ΄ˆκΈ°ν™” μ „, μ‚¬μš© λΆˆκ°€!)
        */

    </script>

    <script>
        /*
        πŸ“Œ 5. λ³€μˆ˜μ˜ λ²”μœ„ (Scope)
        
        1) var : ν•¨μˆ˜ 레벨 μŠ€μ½”ν”„
        2) let, const : 블둝 레벨 μŠ€μ½”ν”„
        */

        console.log("\nπŸ“Œ var μŠ€μ½”ν”„ μ˜ˆμ‹œ");
        if (true) {
            var age = 10; // ν•¨μˆ˜ μ „μ²΄μ—μ„œ μ ‘κ·Ό κ°€λŠ₯
        }
        console.log(age, typeof age); // 10 'number'

        console.log("\nπŸ“Œ let, const μŠ€μ½”ν”„ μ˜ˆμ‹œ");
        if (true) {
            const hobby = "μš΄λ™"; // 블둝 레벨
            let name = "홍길동";
            console.log(hobby, name); // 정상 좜λ ₯
        }
        // console.log(hobby, name); // ❌ ReferenceError (블둝 λ°– μ ‘κ·Ό λΆˆκ°€)

    </script>

    <script>
        /*
        πŸ“Œ 6. 심화 예제 : var vs let 차이
        
        πŸ‘‰ varλŠ” ν•¨μˆ˜ μ „μ²΄μ—μ„œ λ³€μˆ˜ 곡유 β†’ λ°˜λ³΅λ¬Έμ—μ„œ 문제 λ°œμƒ κ°€λŠ₯
        */

        console.log("\nπŸ“Œ var 반볡문 문제점");
        for (var i = 0; i < 3; i++) {
            setTimeout(() => console.log("var i:", i), 100);
        }
        // κ²°κ³Ό: var i: 3, 3, 3 (iκ°€ μ „μ—­μ—μ„œ 곡유됨)

        console.log("\nπŸ“Œ let 반볡문 κ°œμ„ ");
        for (let i = 0; i < 3; i++) {
            setTimeout(() => console.log("let i:", i), 100);
        }
        // κ²°κ³Ό: let i: 0, 1, 2 (각 λΈ”λ‘λ§ˆλ‹€ i λ…λ¦½μ μœΌλ‘œ 쑴재)

    </script>

</body>

</html>