const, let, var

πŸ“ λΈ”λ‘μœ νš¨λ²”μœ„λ₯Ό λ”°λ₯΄λŠ” const

  • λΈ”λ‘μ˜ λ¬Έλ§₯ λ‚΄μ—μ„œ μž¬ν• λ‹Ήν•  수 μ—†λŠ” λ³€μˆ˜ μž…λ‹ˆλ‹€.
  • constλŠ” ν•œ 번 μ„ μ–Έλ˜λ©΄ μž¬ν• λ‹Ήμ΄ λΆˆκ°€λŠ₯ν•œ λ³€μˆ˜λ₯Ό μ„ μ–Έν•˜λŠ” 데 μ‚¬μš©λ©λ‹ˆλ‹€.
  • κ·ΈλŸ¬λ‚˜ const둜 μ„ μ–Έλœ λ³€μˆ˜κ°€ κ°€λ¦¬ν‚€λŠ” κ°’(객체 λ˜λŠ” λ°°μ—΄ λ“±)의 λ‚΄λΆ€λŠ” μˆ˜μ •λ  수 μžˆμŠ΅λ‹ˆλ‹€. μ΄λŠ” λ³€μˆ˜κ°€ μ°Έμ‘°ν•˜λŠ” λ©”λͺ¨λ¦¬ μ£Όμ†Œκ°€ λ³€κ²½λ˜μ§€ μ•ŠλŠ”λ‹€λŠ” μ˜λ―Έμž…λ‹ˆλ‹€.
const discountable = [];

for(let i = 0; i < cart.length; i++){
    discountable.push(i);
}

πŸ“ λΈ”λ‘μœ νš¨λ²”μœ„λ₯Ό λ”°λ₯΄λŠ” let

  • let은 λ³€μˆ˜λ₯Ό μ„ μ–Έν•˜κ³ , ν•„μš”μ— 따라 μž¬ν• λ‹Ήν•  수 μžˆλŠ” ν‚€μ›Œλ“œμž…λ‹ˆλ‹€.
  • let은 블둝 μœ νš¨λ²”μœ„(block scope)λ₯Ό κ°€μ§€λ©°, 블둝 μ™ΈλΆ€μ—μ„œλŠ” ν•΄λ‹Ή λ³€μˆ˜μ— μ ‘κ·Όν•  수 μ—†μŠ΅λ‹ˆλ‹€.
  • 같은 블둝 λ‚΄μ—μ„œ 같은 μ΄λ¦„μ˜ λ³€μˆ˜λ₯Ό μž¬μ„ μ–Έν•  수 μ—†μŠ΅λ‹ˆλ‹€.
if (true) {
    let blockScopedVar = 'I am a block-scoped variable';
    console.log(blockScopedVar); // 유효
}

console.log(blockScopedVar); // μ—λŸ¬: blockScopedVar is not defined

πŸ“ μ–΄νœ˜μ  μœ νš¨λ²”μœ„(lexical scope)λ₯Ό λ”°λ₯΄λŠ” var

  • varλŠ” μ–΄νœ˜μ  μœ νš¨λ²”μœ„(lexical scope)λ₯Ό κ°€μ§€λ©°, ν•¨μˆ˜ μœ νš¨λ²”μœ„λ₯Ό λ”°λ¦…λ‹ˆλ‹€.
  • ν•¨μˆ˜ λ‚΄μ—μ„œ μ„ μ–Έλœ λ³€μˆ˜λŠ” ν•¨μˆ˜ μ „μ²΄μ—μ„œ μ ‘κ·Ό κ°€λŠ₯ν•˜λ©°, ν•¨μˆ˜ μ™ΈλΆ€μ—μ„œλŠ” λ³€μˆ˜μ— μ ‘κ·Όν•  수 μ—†μŠ΅λ‹ˆλ‹€.
  • 같은 ν•¨μˆ˜ λ‚΄μ—μ„œ 같은 μ΄λ¦„μ˜ λ³€μˆ˜λ₯Ό μž¬μ„ μ–Έν•  수 μžˆμŠ΅λ‹ˆλ‹€.
function exampleFunction() {
    var lexicalScopedVar = 'I am a lexical-scoped variable';
    console.log(lexicalScopedVar); // 유효
}

console.log(lexicalScopedVar); // μ—λŸ¬: lexicalScopedVar is not defined

πŸ“ varλ₯Ό μ‚¬μš©ν•˜μ—¬ ν•¨μˆ˜ μœ νš¨λ²”μœ„λ₯Ό λ”°λ₯΄λŠ” ν΄λ‘œμ €

// varλ₯Ό μ‚¬μš©ν•œ ν΄λ‘œμ € 예제
function createClosureVar() {
    var closuresVar = [];

    for (var i = 0; i < 5; i++) {
        closuresVar.push(function () {
            console.log(i);
        });
    }

    return closuresVar;
}

var closuresVarArray = createClosureVar();

// ν΄λ‘œμ € 호좜
for (var j = 0; j < closuresVarArray.length; j++) {
    closuresVarArray[j](); // λͺ¨λ“  ν΄λ‘œμ €κ°€ 5λ₯Ό 좜λ ₯
}
  • varλ₯Ό μ‚¬μš©ν•œ 경우, for λ£¨ν”„μ—μ„œ μƒμ„±λœ ν΄λ‘œμ €κ°€ iλ₯Ό μ°Έμ‘°ν•˜κ³  μžˆμŠ΅λ‹ˆλ‹€.
  • ν•˜μ§€λ§Œ varλŠ” ν•¨μˆ˜ μŠ€μ½”ν”„λ₯Ό κ°–κΈ° λ•Œλ¬Έμ— for 루프가 μ’…λ£Œλœ 후에도 iλŠ” μ „μ—­ μŠ€μ½”ν”„μ— 남아 있고, ν΄λ‘œμ €λŠ” 항상 μ „μ—­ μŠ€μ½”ν”„μ— μžˆλŠ” iλ₯Ό μ°Έμ‘°ν•©λ‹ˆλ‹€.
  • λ”°λΌμ„œ ν΄λ‘œμ €λ₯Ό ν˜ΈμΆœν•  λ•Œ λͺ¨λ“  ν΄λ‘œμ €κ°€ i의 μ΅œμ’… 값인 5λ₯Ό 좜λ ₯ν•©λ‹ˆλ‹€.

πŸ“ let을 μ‚¬μš©ν•˜μ—¬ ν΄λ‘œμ € 문제λ₯Ό ν•΄κ²°ν•œ μ½”λ“œ

// let을 μ‚¬μš©ν•œ ν΄λ‘œμ € 예제
function createClosureLet() {
    var closuresLet = [];

    for (let i = 0; i < 5; i++) {
        closuresLet.push(function () {
            console.log(i);
        });
    }

    return closuresLet;
}

var closuresLetArray = createClosureLet();

// ν΄λ‘œμ € 호좜
for (let j = 0; j < closuresLetArray.length; j++) {
    closuresLetArray[j](); // 각 ν΄λ‘œμ €κ°€ ν•΄λ‹Ήν•˜λŠ” κ°’(0λΆ€ν„° 4κΉŒμ§€)을 좜λ ₯
}
  • let을 μ‚¬μš©ν•œ 경우, for λ£¨ν”„μ—μ„œ μƒμ„±λœ ν΄λ‘œμ €κ°€ iλ₯Ό μ°Έμ‘°ν•˜κ³  μžˆμŠ΅λ‹ˆλ‹€.
  • let은 블둝 μŠ€μ½”ν”„λ₯Ό κ°–κΈ° λ•Œλ¬Έμ— 각 ν΄λ‘œμ €λŠ” ν•΄λ‹Ή λΈ”λ‘μ—μ„œμ˜ iλ₯Ό μ°Έμ‘°ν•©λ‹ˆλ‹€.
  • λ”°λΌμ„œ ν΄λ‘œμ €λ₯Ό ν˜ΈμΆœν•  λ•Œ 각각의 ν΄λ‘œμ €λŠ” μžμ‹ μ΄ μƒμ„±λœ μ‹œμ μ˜ i 값을 좜λ ₯ν•˜κ²Œ λ©λ‹ˆλ‹€.

πŸ“ 블둝 μœ νš¨λ²”μœ„ (Block Scope)

  • 블둝 μœ νš¨λ²”μœ„λŠ” μ€‘κ΄„ν˜Έ {}둜 λ‘˜λŸ¬μ‹ΈμΈ μ˜μ—­μ„ κ°€λ¦¬ν‚΅λ‹ˆλ‹€.
  • let 및 const ν‚€μ›Œλ“œλ‘œ μ„ μ–Έλœ λ³€μˆ˜λŠ” 블둝 유효 λ²”μœ„λ₯Ό κ°€μ§‘λ‹ˆλ‹€. 즉, ν•΄λ‹Ή λ³€μˆ˜λŠ” κ·Έ λ³€μˆ˜κ°€ μ„ μ–Έλœ 블둝 λ‚΄μ—μ„œλ§Œ μœ νš¨ν•˜λ©° μ™ΈλΆ€μ—μ„œ μ ‘κ·Όν•  수 μ—†μŠ΅λ‹ˆλ‹€.
  • 블둝은 주둜 쑰건문 (if, else, for, while λ“±) λ‚΄λΆ€, ν•¨μˆ˜ λ‚΄λΆ€, λ˜λŠ” 단독 μ€‘κ΄„ν˜Έ λΈ”λ‘μœΌλ‘œ μ •μ˜λ©λ‹ˆλ‹€.

πŸ“ μ–΄νœ˜μ  μœ νš¨λ²”μœ„ (Lexical Scope λ˜λŠ” Static Scope)

μ–΄νœ˜μ  μœ νš¨λ²”μœ„λŠ” μ½”λ“œλ₯Ό μž‘μ„±ν•˜λŠ” μ‹œμ μ— κ²°μ •λ˜λŠ” μŠ€μ½”ν”„μ˜ μ’…λ₯˜μž…λ‹ˆλ‹€. λ³€μˆ˜κ°€ μ–΄λ””μ—μ„œ μ„ μ–Έλ˜μ—ˆλŠ”μ§€μ— 따라 κ·Έ λ³€μˆ˜μ˜ 유효 λ²”μœ„κ°€ μ •ν•΄μ§‘λ‹ˆλ‹€. μ–΄νœ˜μ  μœ νš¨λ²”μœ„λŠ” ν•¨μˆ˜λ₯Ό 어디에 μž‘μ„±ν–ˆλŠ”μ§€μ— 따라 ν•¨μˆ˜μ˜ μŠ€μ½”ν”„κ°€ κ²°μ •λ˜λŠ” 것을 μ˜λ―Έν•©λ‹ˆλ‹€.
function outer() {
  let outerVar = 'I am outer';

  function inner() {
    let innerVar = 'I am inner';
    console.log(outerVar); // outerVarλŠ” μ–΄νœ˜μ  μœ νš¨λ²”μœ„μ— μ˜ν•΄ μ ‘κ·Ό κ°€λŠ₯
    console.log(innerVar); // innerVarλŠ” ν˜„μž¬ μŠ€μ½”ν”„μ— μ„ μ–Έλ˜μ–΄ μžˆμ–΄ 직접 μ ‘κ·Ό κ°€λŠ₯
  }

  inner();

  console.log(outerVar); // outerVarλŠ” μ—¬μ „νžˆ μ–΄νœ˜μ  μœ νš¨λ²”μœ„μ— μ˜ν•΄ μ ‘κ·Ό κ°€λŠ₯
  console.log(innerVar); // Error: innerVarλŠ” outer ν•¨μˆ˜μ˜ μŠ€μ½”ν”„λ₯Ό λ²—μ–΄λ‚˜μ„œ μ ‘κ·Ό λΆˆκ°€λŠ₯
}

outer();
μœ„ μ˜ˆμ œμ—μ„œ inner ν•¨μˆ˜λŠ” μžμ‹ μ˜ μŠ€μ½”ν”„μ™€ μ™ΈλΆ€ ν•¨μˆ˜μΈ outer ν•¨μˆ˜μ˜ μŠ€μ½”ν”„μ— μ ‘κ·Όν•  수 μžˆμŠ΅λ‹ˆλ‹€. μ΄λŠ” μ–΄νœ˜μ  μœ νš¨λ²”μœ„μ— μ˜ν•œ κ²ƒμž…λ‹ˆλ‹€. λ³€μˆ˜μ˜ 유효 λ²”μœ„λŠ” μ½”λ“œλ₯Ό μž‘μ„±ν•˜λŠ” μ‹œμ μ— 이미 μ •ν•΄μ Έ μžˆμŠ΅λ‹ˆλ‹€.

πŸ“ ν•¨μˆ˜ μœ νš¨λ²”μœ„ (Function Scope)

ν•¨μˆ˜ μœ νš¨λ²”μœ„λŠ” ν•¨μˆ˜ λ‚΄μ—μ„œ μ„ μ–Έλœ λ³€μˆ˜κ°€ ν•¨μˆ˜ λ‚΄λΆ€μ—μ„œλ§Œ μœ νš¨ν•˜λ‹€λŠ” 원칙을 λ‚˜νƒ€λƒ…λ‹ˆλ‹€. ν•¨μˆ˜ μœ νš¨λ²”μœ„λŠ” ν•¨μˆ˜κ°€ 싀행될 λ•Œλ§ˆλ‹€ μƒˆλ‘œμš΄ μŠ€μ½”ν”„κ°€ μƒμ„±λ˜λ©°, ν•¨μˆ˜ λ‚΄μ—μ„œ μ„ μ–Έλœ λ³€μˆ˜λŠ” ν•΄λ‹Ή ν•¨μˆ˜ λ‚΄μ—μ„œλ§Œ μ ‘κ·Όν•  수 μžˆμŠ΅λ‹ˆλ‹€.
function exampleFunction() {
  let localVar = 'I am a local variable'; // ν•¨μˆ˜ μœ νš¨λ²”μœ„μ— μ†ν•œ λ³€μˆ˜

  if (true) {
    let blockVar = 'I am a block-scoped variable'; // 블둝 μœ νš¨λ²”μœ„μ— μ†ν•œ λ³€μˆ˜
    console.log(localVar); // ν•¨μˆ˜ μœ νš¨λ²”μœ„ λ‚΄μ—μ„œ μ ‘κ·Ό κ°€λŠ₯
    console.log(blockVar); // 블둝 μœ νš¨λ²”μœ„ λ‚΄μ—μ„œ μ ‘κ·Ό κ°€λŠ₯
  }

  console.log(localVar); // ν•¨μˆ˜ μœ νš¨λ²”μœ„ λ‚΄μ—μ„œ μ ‘κ·Ό κ°€λŠ₯
  console.log(blockVar); // Error: 블둝 μœ νš¨λ²”μœ„λ₯Ό λ²—μ–΄λ‚œ κ³³μ—μ„œλŠ” μ ‘κ·Ό λΆˆκ°€λŠ₯
}
μœ„ μ˜ˆμ œμ—μ„œ localVarλŠ” ν•¨μˆ˜ μœ νš¨λ²”μœ„ λ‚΄μ—μ„œ μ„ μ–Έλ˜μ–΄ ν•¨μˆ˜ μ „μ²΄μ—μ„œ μ ‘κ·Ό κ°€λŠ₯ν•©λ‹ˆλ‹€. ν•˜μ§€λ§Œ blockVarλŠ” 블둝 λ‚΄μ—μ„œλ§Œ μœ νš¨ν•œ λ³€μˆ˜μ΄λ―€λ‘œ 블둝 μ™ΈλΆ€μ—μ„œλŠ” μ ‘κ·Όν•  수 μ—†μŠ΅λ‹ˆλ‹€.

μš”μ•½ν•˜λ©΄, μ–΄νœ˜μ  μœ νš¨λ²”μœ„λŠ” μ½”λ“œλ₯Ό μž‘μ„±ν•˜λŠ” μ‹œμ μ— λ³€μˆ˜μ˜ μŠ€μ½”ν”„κ°€ κ²°μ •λ˜λ©°, ν•¨μˆ˜ μœ νš¨λ²”μœ„λŠ” ν•¨μˆ˜κ°€ 싀행될 λ•Œ μƒμ„±λ˜λŠ” μŠ€μ½”ν”„μž…λ‹ˆλ‹€. ν•¨μˆ˜ μœ νš¨λ²”μœ„λŠ” μ–΄νœ˜μ  μœ νš¨λ²”μœ„λ₯Ό λ”°λ₯΄κΈ° λ•Œλ¬Έμ— ν•¨μˆ˜κ°€ 어디에 μ„ μ–Έλ˜μ—ˆλŠ”μ§€μ— 따라 μŠ€μ½”ν”„κ°€ κ²°μ •λ©λ‹ˆλ‹€.