λ³Έλ¬Έ λ°”λ‘œκ°€κΈ°
Language/Javascript

[Javascript]μžλ°”μŠ€ν¬λ¦½νŠΈ μŠ€μ½”ν”„ μ™„λ²½ κ°€μ΄λ“œ: κΈ°μ΄ˆλΆ€ν„° κ³ κΈ‰κΉŒμ§€

by YJ Dev 2024. 7. 4.
728x90
λ°˜μ‘ν˜•
SMALL

μžλ°”μŠ€ν¬λ¦½νŠΈλ₯Ό λ‹€λ£¨λŠ” 데 μžˆμ–΄μ„œ 'μŠ€μ½”ν”„'λŠ” 맀우 μ€‘μš”ν•œ κ°œλ…μž…λ‹ˆλ‹€. μŠ€μ½”ν”„λ₯Ό μ΄ν•΄ν•˜λ©΄ μ½”λ“œμ˜ 가독성을 높이고, 버그λ₯Ό μ€„μ΄λŠ” 데 큰 도움이 λ©λ‹ˆλ‹€. 이번 κΈ€μ—μ„œλŠ” μžλ°”μŠ€ν¬λ¦½νŠΈ μŠ€μ½”ν”„μ— λŒ€ν•΄ κΈ°μ΄ˆλΆ€ν„° κ³ κΈ‰κΉŒμ§€ μ²΄κ³„μ μœΌλ‘œ μ•Œμ•„λ³΄κ² μŠ΅λ‹ˆλ‹€.

μžλ°”μŠ€ν¬λ¦½νŠΈ μŠ€μ½”ν”„


01. μžλ°”μŠ€ν¬λ¦½νŠΈ μŠ€μ½”ν”„λž€β“

μžλ°”μŠ€ν¬λ¦½νŠΈμ—μ„œ μŠ€μ½”ν”„(scope)λŠ” λ³€μˆ˜λ‚˜ ν•¨μˆ˜κ°€ μ ‘κ·Όν•  수 μžˆλŠ” 유효 λ²”μœ„λ₯Ό μ˜λ―Έν•©λ‹ˆλ‹€. μ΄λŠ” μ½”λ“œμ˜ μ‹€ν–‰ μ»¨ν…μŠ€νŠΈμ™€ λ°€μ ‘ν•œ 관련이 있으며, μŠ€μ½”ν”„λ₯Ό 잘 이해해야 μ½”λ“œμ˜ 흐름을 μ •ν™•νžˆ νŒŒμ•…ν•  수 μžˆμŠ΅λ‹ˆλ‹€. μžλ°”μŠ€ν¬λ¦½νŠΈμ—λŠ” 주둜 μ „μ—­ μŠ€μ½”ν”„μ™€ 지역 μŠ€μ½”ν”„ 두 가지 μœ ν˜•μ˜ μŠ€μ½”ν”„κ°€ μžˆμŠ΅λ‹ˆλ‹€.

  • μ „μ—­ μŠ€μ½”ν”„: μ „μ—­ μŠ€μ½”ν”„μ— μ„ μ–Έλœ λ³€μˆ˜λŠ” μ½”λ“œ μ–΄λ””μ—μ„œλ‚˜ μ ‘κ·Όν•  수 μžˆμŠ΅λ‹ˆλ‹€. μ „μ—­ λ³€μˆ˜λŠ” ν•¨μˆ˜ λ°–μ΄λ‚˜ μ½”λ“œ 블둝 λ°–μ—μ„œ μ„ μ–Έλœ λ³€μˆ˜μž…λ‹ˆλ‹€.
  • 지역 μŠ€μ½”ν”„: 지역 μŠ€μ½”ν”„μ— μ„ μ–Έλœ λ³€μˆ˜λŠ” ν•΄λ‹Ή ν•¨μˆ˜ λ‚΄μ—μ„œλ§Œ μ ‘κ·Όν•  수 μžˆμŠ΅λ‹ˆλ‹€. ν•¨μˆ˜ λ‚΄μ—μ„œ μ„ μ–Έλœ λ³€μˆ˜λŠ” 지역 λ³€μˆ˜μž…λ‹ˆλ‹€.

02. μžλ°”μŠ€ν¬λ¦½νŠΈ μŠ€μ½”ν”„μ˜ μ’…λ₯˜πŸ—‚️

1. μ „μ—­ μŠ€μ½”ν”„ (Global Scope)

  • μ „μ—­ μŠ€μ½”ν”„μ— μ„ μ–Έλœ λ³€μˆ˜μ™€ ν•¨μˆ˜λŠ” μ½”λ“œ μ–΄λ””μ„œλ“  μ ‘κ·Όν•  수 μžˆμŠ΅λ‹ˆλ‹€.
  • μ „μ—­ μŠ€μ½”ν”„μ— λ³€μˆ˜λ₯Ό μ„ μ–Έν•  λ•ŒλŠ” var, let, constλ₯Ό μ‚¬μš©ν•  수 μžˆμ§€λ§Œ, varλŠ” μ „μ—­ 객체의 μ†μ„±μœΌλ‘œ μΆ”κ°€λ˜κ³ , letκ³Ό constλŠ” μ „μ—­ 객체의 속성이 λ˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€.
var globalVar = "I'm a global variable";
let globalLet = "I'm also global";
const globalConst = "I'm a constant global variable";

2. ν•¨μˆ˜ μŠ€μ½”ν”„ (Function Scope)

  • ν•¨μˆ˜ μŠ€μ½”ν”„μ— μ„ μ–Έλœ λ³€μˆ˜λŠ” ν•΄λ‹Ή ν•¨μˆ˜ λ‚΄μ—μ„œλ§Œ μ ‘κ·Όν•  수 μžˆμŠ΅λ‹ˆλ‹€.
  • var둜 μ„ μ–Έλœ λ³€μˆ˜λŠ” ν•¨μˆ˜ 레벨 μŠ€μ½”ν”„λ₯Ό 가지며, ν•¨μˆ˜ λ‚΄λΆ€ μ–΄λ””μ„œλ“  μ ‘κ·Ό κ°€λŠ₯ν•©λ‹ˆλ‹€.
function myFunction() {
    var functionVar = "I'm inside a function";
    console.log(functionVar); // μ ‘κ·Ό κ°€λŠ₯
}
console.log(functionVar); // μ ‘κ·Ό λΆˆκ°€, 였λ₯˜ λ°œμƒ

3. 블둝 μŠ€μ½”ν”„ (Block Scope)

  • 블둝 μŠ€μ½”ν”„λŠ” {}둜 감싸진 블둝 λ‚΄μ—μ„œλ§Œ λ³€μˆ˜κ°€ μ ‘κ·Ό κ°€λŠ₯ν•˜λ„λ‘ ν•©λ‹ˆλ‹€.
  • letκ³Ό constλŠ” 블둝 레벨 μŠ€μ½”ν”„λ₯Ό 가지며, 블둝 λ‚΄λΆ€μ—μ„œλ§Œ μ ‘κ·Όν•  수 μžˆμŠ΅λ‹ˆλ‹€.
if (true) {
    let blockLet = "I'm inside a block";
    const blockConst = "I'm also inside a block";
    console.log(blockLet); // μ ‘κ·Ό κ°€λŠ₯
    console.log(blockConst); // μ ‘κ·Ό κ°€λŠ₯
}
console.log(blockLet); // μ ‘κ·Ό λΆˆκ°€, 였λ₯˜ λ°œμƒ
console.log(blockConst); // μ ‘κ·Ό λΆˆκ°€, 였λ₯˜ λ°œμƒ

4. λͺ¨λ“ˆ μŠ€μ½”ν”„ (Module Scope)

  • μžλ°”μŠ€ν¬λ¦½νŠΈ ES6λΆ€ν„° λͺ¨λ“ˆμ΄ λ„μž…λ˜λ©΄μ„œ λͺ¨λ“ˆ μŠ€μ½”ν”„κ°€ μƒκ²ΌμŠ΅λ‹ˆλ‹€.
  • λͺ¨λ“ˆ λ‚΄μ—μ„œ μ„ μ–Έλœ λ³€μˆ˜μ™€ ν•¨μˆ˜λŠ” λͺ¨λ“ˆ λ‚΄λΆ€μ—μ„œλ§Œ μ ‘κ·Ό κ°€λŠ₯ν•˜λ©°, λ‹€λ₯Έ λͺ¨λ“ˆμ—μ„œ μ ‘κ·Όν•˜λ €λ©΄ λͺ…μ‹œμ μœΌλ‘œ export와 importλ₯Ό μ‚¬μš©ν•΄μ•Ό ν•©λ‹ˆλ‹€.
// module.js
export const moduleVar = "I'm in a module";

// main.js
import { moduleVar } from './module.js';
console.log(moduleVar); // "I'm in a module"

03. λ³€μˆ˜ μ„ μ–Έκ³Ό μŠ€μ½”ν”„πŸ“

μžλ°”μŠ€ν¬λ¦½νŠΈμ—μ„œ λ³€μˆ˜ μ„ μ–Έκ³Ό μŠ€μ½”ν”„λŠ” λ³€μˆ˜μ˜ 생λͺ… 주기와 μ ‘κ·Ό κ°€λŠ₯성을 μ •μ˜ν•©λ‹ˆλ‹€. λ³€μˆ˜ μ„ μ–Έμ—λŠ” var, let, const ν‚€μ›Œλ“œκ°€ μ‚¬μš©λ˜λ©°, 각각은 μ„œλ‘œ λ‹€λ₯Έ μŠ€μ½”ν”„ κ·œμΉ™μ„ λ”°λ¦…λ‹ˆλ‹€. 이λ₯Ό μ΄ν•΄ν•˜κΈ° μœ„ν•΄ 각 ν‚€μ›Œλ“œμ™€ μŠ€μ½”ν”„μ˜ 관계λ₯Ό μžμ„Ένžˆ μ‚΄νŽ΄λ³΄κ² μŠ΅λ‹ˆλ‹€.
Javascript var, let, const λ³€μˆ˜μ— κ΄€ν•œ λ‚΄μš©μ€ μ•„λž˜ ν¬μŠ€νŒ…μ„ μ°Έκ³ ν•΄ μ£Όμ„Έμš”πŸ˜

""

[Javascript]μžλ°”μŠ€ν¬λ¦½νŠΈ λ³€μˆ˜ μ΄ν•΄ν•˜κΈ°: var, let, const 차이점

μžλ°”μŠ€ν¬λ¦½νŠΈ λ³€μˆ˜λŠ” ν”„λ‘œκ·Έλž˜λ°μ˜ 핡심 μš”μ†Œλ‘œ, 데이터λ₯Ό μ €μž₯ν•˜κ³  μ‘°μž‘ν•˜λŠ” 데 ν•„μˆ˜μ μΈ 역할을 ν•©λ‹ˆλ‹€. 이번 ν¬μŠ€νŒ…μ—μ„œλŠ” μžλ°”μŠ€ν¬λ¦½νŠΈμ—μ„œ λ³€μˆ˜λ₯Ό μ„ μ–Έν•˜κ³  μ‚¬μš©ν•˜λŠ” 방법을 μžμ„Ένžˆ μ„€λͺ…

creativevista.tistory.com

var

var ν‚€μ›Œλ“œλŠ” ν•¨μˆ˜ μŠ€μ½”ν”„λ₯Ό λ”°λ¦…λ‹ˆλ‹€. 즉, ν•¨μˆ˜ λ‚΄μ—μ„œ μ„ μ–Έλœ λ³€μˆ˜λŠ” ν•¨μˆ˜ λ‚΄ μ–΄λ””μ„œλ‚˜ μ ‘κ·Όν•  수 있으며, 블둝 μŠ€μ½”ν”„λŠ” λ¬΄μ‹œλ©λ‹ˆλ‹€.

function varTest() {
    if (true) {
        var x = 1;
    }
    console.log(x);  // 1 (varλŠ” ν•¨μˆ˜ μŠ€μ½”ν”„λ₯Ό λ”°λ₯΄λ―€λ‘œ ν•¨μˆ˜ λ‚΄λΆ€ μ–΄λ””μ„œλ“  μ ‘κ·Ό κ°€λŠ₯)
}

varTest();

μœ„ μ˜ˆμ‹œμ—μ„œ xλŠ” if 블둝 λ‚΄μ—μ„œ μ„ μ–Έλ˜μ—ˆμ§€λ§Œ, ν•¨μˆ˜ μŠ€μ½”ν”„λ₯Ό λ”°λ₯΄λ―€λ‘œ ν•¨μˆ˜ λ‚΄ μ–΄λ””μ„œλ“  μ ‘κ·Όν•  수 μžˆμŠ΅λ‹ˆλ‹€.


let

let ν‚€μ›Œλ“œλŠ” 블둝 μŠ€μ½”ν”„λ₯Ό λ”°λ¦…λ‹ˆλ‹€. 즉, μ€‘κ΄„ν˜Έ {}둜 감싸진 블둝 λ‚΄μ—μ„œλ§Œ μœ νš¨ν•©λ‹ˆλ‹€.

function letTest() {
    if (true) {
        let y = 1;
        console.log(y);  // 1 (let은 블둝 μŠ€μ½”ν”„λ₯Ό 따름)
    }
    console.log(y);  // ReferenceError: y is not defined (블둝 μ™ΈλΆ€μ—μ„œλŠ” μ ‘κ·Ό λΆˆκ°€)
}

letTest();

μœ„ μ˜ˆμ‹œμ—μ„œ yλŠ” if 블둝 λ‚΄μ—μ„œλ§Œ μœ νš¨ν•˜λ©°, 블둝 μ™ΈλΆ€μ—μ„œλŠ” μ ‘κ·Όν•  수 μ—†μŠ΅λ‹ˆλ‹€.


const

const ν‚€μ›Œλ“œλŠ” letκ³Ό λ§ˆμ°¬κ°€μ§€λ‘œ 블둝 μŠ€μ½”ν”„λ₯Ό λ”°λ¦…λ‹ˆλ‹€. λ˜ν•œ, const둜 μ„ μ–Έλœ λ³€μˆ˜λŠ” μ„ μ–Έ μ‹œ 값을 ν• λ‹Ήν•΄μ•Ό ν•˜λ©°, 이후에 값을 λ³€κ²½ν•  수 μ—†μŠ΅λ‹ˆλ‹€.

function constTest() {
    if (true) {
        const z = 1;
        console.log(z);  // 1 (constλŠ” 블둝 μŠ€μ½”ν”„λ₯Ό 따름)
    }
    console.log(z);  // ReferenceError: z is not defined (블둝 μ™ΈλΆ€μ—μ„œλŠ” μ ‘κ·Ό λΆˆκ°€)
}

constTest();

μœ„ μ˜ˆμ‹œμ—μ„œ zλŠ” if 블둝 λ‚΄μ—μ„œλ§Œ μœ νš¨ν•˜λ©°, 블둝 μ™ΈλΆ€μ—μ„œλŠ” μ ‘κ·Όν•  수 μ—†μŠ΅λ‹ˆλ‹€. λ˜ν•œ, constλŠ” 값을 μž¬ν• λ‹Ήν•  수 μ—†μŠ΅λ‹ˆλ‹€.


04. μŠ€μ½”ν”„ 체인(Scope Chain)πŸ”—

μŠ€μ½”ν”„ 체인(Scope Chain)은 μžλ°”μŠ€ν¬λ¦½νŠΈμ˜ λ³€μˆ˜ μ ‘κ·Ό κ·œμΉ™μ„ μ΄ν•΄ν•˜λŠ” 데 핡심적인 κ°œλ…μž…λ‹ˆλ‹€. μ΄λŠ” νŠΉμ • μŠ€μ½”ν”„ λ‚΄μ—μ„œ λ³€μˆ˜λ₯Ό 찾지 λͺ»ν•  경우 μ™ΈλΆ€ μŠ€μ½”ν”„λ‘œ λ²”μœ„λ₯Ό ν™•μž₯ν•˜λ©° λ³€μˆ˜λ₯Ό μ°ΎλŠ” λ©”μ»€λ‹ˆμ¦˜μ„ μ„€λͺ…ν•©λ‹ˆλ‹€. μŠ€μ½”ν”„ 체인을 톡해 μžλ°”μŠ€ν¬λ¦½νŠΈλŠ” λ³€μˆ˜λ₯Ό κ²€μƒ‰ν•˜λŠ” 과정을 λ‹¨κ³„μ μœΌλ‘œ μˆ˜ν–‰ν•©λ‹ˆλ‹€.

μŠ€μ½”ν”„ 체인의 ꡬ쑰

μŠ€μ½”ν”„ 체인은 ν˜„μž¬ μŠ€μ½”ν”„μ—μ„œλΆ€ν„° μ‹œμž‘ν•˜μ—¬ μƒμœ„ μŠ€μ½”ν”„λ‘œ μ΄λ™ν•˜λ©° λ³€μˆ˜λ₯Ό κ²€μƒ‰ν•©λ‹ˆλ‹€. 이 체인은 μ „μ—­ μŠ€μ½”ν”„κΉŒμ§€ 이어지며, μ „μ—­ μŠ€μ½”ν”„μ—μ„œλ„ λ³€μˆ˜λ₯Ό 찾지 λͺ»ν•˜λ©΄ ReferenceErrorλ₯Ό λ°œμƒμ‹œν‚΅λ‹ˆλ‹€.

μ˜ˆμ‹œ μ½”λ“œ

μ•„λž˜ μ˜ˆμ‹œλ₯Ό 톡해 μŠ€μ½”ν”„ 체인이 μ–΄λ–»κ²Œ μž‘λ™ν•˜λŠ”μ§€ μ„€λͺ…ν•˜κ² μŠ΅λ‹ˆλ‹€.

var globalVar = "I am a global variable";

function outerFunction() {
    var outerVar = "I am an outer variable";
    
    function innerFunction() {
        var innerVar = "I am an inner variable";
        
        console.log(innerVar);   // "I am an inner variable"
        console.log(outerVar);   // "I am an outer variable"
        console.log(globalVar);  // "I am a global variable"
    }
    
    innerFunction();
}

outerFunction();

μŠ€μ½”ν”„ 체인의 λ™μž‘

1. innerFunction의 μŠ€μ½”ν”„:

  • innerVarλŠ” innerFunction의 지역 λ³€μˆ˜μž…λ‹ˆλ‹€. λ”°λΌμ„œ λ°”λ‘œ 찾을 수 μžˆμŠ΅λ‹ˆλ‹€.
  • outerVarλŠ” innerFunction의 μŠ€μ½”ν”„μ— μ—†μœΌλ―€λ‘œ, ν•œ 단계 μœ„μ˜ μŠ€μ½”ν”„μΈ outerFunctionμ—μ„œ μ°ΎμŠ΅λ‹ˆλ‹€.
  • globalVarλŠ” outerFunction에도 μ—†μœΌλ―€λ‘œ, μ΅œμƒμœ„ μŠ€μ½”ν”„μΈ μ „μ—­ μŠ€μ½”ν”„μ—μ„œ μ°ΎμŠ΅λ‹ˆλ‹€.

2. outerFunction의 μŠ€μ½”ν”„:

  • outerFunction λ‚΄μ—μ„œλŠ” outerVarλ₯Ό λ°”λ‘œ 찾을 수 μžˆμŠ΅λ‹ˆλ‹€.
  • μ „μ—­ λ³€μˆ˜ globalVar도 찾을 수 μžˆμŠ΅λ‹ˆλ‹€.
  • ν•˜μ§€λ§Œ innerVarλŠ” innerFunction λ‚΄λΆ€μ˜ λ³€μˆ˜μ΄λ―€λ‘œ outerFunctionμ—μ„œλŠ” μ ‘κ·Όν•  수 μ—†μŠ΅λ‹ˆλ‹€.

μŠ€μ½”ν”„ 체인의 μ‹œκ°μ  ν‘œν˜„

Global Scope
  - globalVar
    |
Outer Function Scope
  - outerVar
    |
Inner Function Scope
  - innerVar

ν•¨μˆ˜ ν΄λ‘œμ €μ™€ μŠ€μ½”ν”„ 체인

μŠ€μ½”ν”„ 체인은 ν΄λ‘œμ €μ™€ λ°€μ ‘ν•œ 관련이 μžˆμŠ΅λ‹ˆλ‹€. ν΄λ‘œμ €λŠ” ν•¨μˆ˜κ°€ 선언될 λ•Œμ˜ λ ‰μ‹œμ»¬ μŠ€μ½”ν”„(lexical scope)λ₯Ό κΈ°μ–΅ν•˜κ³  이λ₯Ό μ°Έμ‘°ν•  수 μžˆλŠ” κΈ°λŠ₯μž…λ‹ˆλ‹€.

function makeFunction() {
    var name = "Mozilla";
    function displayName() {
        console.log(name);
    }
    return displayName;
}

var myFunc = makeFunction();
myFunc();  // "Mozilla"

makeFunction이 μ‹€ν–‰λ˜κ³  λ‚˜λ©΄ displayName이 λ°˜ν™˜λ©λ‹ˆλ‹€. λ°˜ν™˜λœ ν•¨μˆ˜λŠ” μ—¬μ „νžˆ makeFunction의 μŠ€μ½”ν”„ 체인을 κΈ°μ–΅ν•˜κ³  μžˆμ–΄ name λ³€μˆ˜μ— μ ‘κ·Όν•  수 μžˆμŠ΅λ‹ˆλ‹€. μ΄λŠ” ν΄λ‘œμ €μ™€ μŠ€μ½”ν”„ 체인이 μ–΄λ–»κ²Œ μƒν˜Έμž‘μš©ν•˜λŠ”μ§€λ₯Ό λ³΄μ—¬μ€λ‹ˆλ‹€.


05. ν˜Έμ΄μŠ€νŒ…(Hoisting)⬆️

ν˜Έμ΄μŠ€νŒ…(Hoisting)은 μžλ°”μŠ€ν¬λ¦½νŠΈμ—μ„œ λ³€μˆ˜μ™€ ν•¨μˆ˜ 선언이 κ·Έ λ²”μœ„μ˜ 맨 μœ„λ‘œ λŒμ–΄μ˜¬λ €μ§€λŠ” λ™μž‘μ„ μ˜λ―Έν•©λ‹ˆλ‹€. 즉, μ½”λ“œκ°€ μ‹€μ œλ‘œ μ‹€ν–‰λ˜κΈ° 전에 λ³€μˆ˜μ™€ ν•¨μˆ˜ 선언이 ν•΄λ‹Ή λ²”μœ„μ˜ 맨 μœ„λ‘œ μ΄λ™λœ κ²ƒμ²˜λŸΌ λ™μž‘ν•©λ‹ˆλ‹€. κ·ΈλŸ¬λ‚˜ λ³€μˆ˜ 할당은 ν˜Έμ΄μŠ€νŒ… λ˜μ§€ μ•ŠμœΌλ©°, μ΄ˆκΈ°ν™”λŠ” μ—¬μ „νžˆ μ½”λ“œμ˜ μ›λž˜ μœ„μΉ˜μ—μ„œ μ΄λ£¨μ–΄μ§‘λ‹ˆλ‹€.

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

μžλ°”μŠ€ν¬λ¦½νŠΈλŠ” var ν‚€μ›Œλ“œλ₯Ό μ‚¬μš©ν•˜μ—¬ μ„ μ–Έλœ λ³€μˆ˜λ₯Ό μŠ€μ½”ν”„μ˜ μ΅œμƒλ‹¨μœΌλ‘œ ν˜Έμ΄μŠ€νŒ…ν•©λ‹ˆλ‹€. κ·ΈλŸ¬λ‚˜ λ³€μˆ˜μ˜ μ΄ˆκΈ°ν™”λŠ” μ½”λ“œ μ‹€ν–‰ νλ¦„μ—μ„œ λ³€μˆ˜ μ„ μ–Έ 이후에 μ΄λ£¨μ–΄μ§‘λ‹ˆλ‹€.

console.log(x);  // undefined
var x = 5;
console.log(x);  // 5

μœ„ μ˜ˆμ‹œλŠ” λ‹€μŒκ³Ό 같이 해석될 수 μžˆμŠ΅λ‹ˆλ‹€.

var x;           // λ³€μˆ˜ 선언이 ν˜Έμ΄μŠ€νŒ…λ¨
console.log(x);  // μ΄ˆκΈ°ν™”λ˜μ§€ μ•Šμ•˜μœΌλ―€λ‘œ undefined 좜λ ₯
x = 5;           // λ³€μˆ˜μ— κ°’ ν• λ‹Ή
console.log(x);  // 5 좜λ ₯

letκ³Ό const의 ν˜Έμ΄μŠ€νŒ…

letκ³Ό const ν‚€μ›Œλ“œλ‘œ μ„ μ–Έλœ λ³€μˆ˜λ„ ν˜Έμ΄μŠ€νŒ…λ˜μ§€λ§Œ, 이듀은 "μΌμ‹œμ  μ‚¬κ°μ§€λŒ€(Temporal Dead Zone, TDZ)"에 λ†“μ΄κ²Œ λ˜μ–΄ μ΄ˆκΈ°ν™” 전에 μ ‘κ·Όν•˜λ €κ³  ν•˜λ©΄ ReferenceErrorκ°€ λ°œμƒν•©λ‹ˆλ‹€.

console.log(y);  // ReferenceError: y is not defined
let y = 10;
console.log(y);  // 10

μœ„ μ˜ˆμ‹œλŠ” λ‹€μŒκ³Ό 같이 해석될 수 μžˆμŠ΅λ‹ˆλ‹€.

let y;           // λ³€μˆ˜ 선언이 ν˜Έμ΄μŠ€νŒ…λ¨, TDZ에 듀어감
console.log(y);  // TDZ에 μžˆμœΌλ―€λ‘œ ReferenceError λ°œμƒ
y = 10;          // TDZλ₯Ό λ²—μ–΄λ‚˜λ©° λ³€μˆ˜μ— κ°’ ν• λ‹Ή
console.log(y);  // 10 좜λ ₯

const도 λ§ˆμ°¬κ°€μ§€μž…λ‹ˆλ‹€.

console.log(z);  // ReferenceError: z is not defined
const z = 15;
console.log(z);  // 15

ν•¨μˆ˜ ν˜Έμ΄μŠ€νŒ…

ν•¨μˆ˜ 선언도 ν˜Έμ΄μŠ€νŒ…λ©λ‹ˆλ‹€. ν•¨μˆ˜ 전체가 λŒμ–΄μ˜¬λ €μ§€λ―€λ‘œ ν•¨μˆ˜κ°€ μ„ μ–Έλ˜κΈ° 전에 ν˜ΈμΆœν•  수 μžˆμŠ΅λ‹ˆλ‹€.

sayHello();  // "Hello, World!" 좜λ ₯

function sayHello() {
    console.log("Hello, World!");
}

μœ„ μ˜ˆμ‹œλŠ” λ‹€μŒκ³Ό 같이 해석될 수 μžˆμŠ΅λ‹ˆλ‹€.

function sayHello() {  // ν•¨μˆ˜ 선언이 ν˜Έμ΄μŠ€νŒ…λ¨
    console.log("Hello, World!");
}

sayHello();  // "Hello, World!" 좜λ ₯

κ·ΈλŸ¬λ‚˜ ν•¨μˆ˜ ν‘œν˜„μ‹μ€ ν˜Έμ΄μŠ€νŒ…λ˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€. λ³€μˆ˜ ν˜Έμ΄μŠ€νŒ… κ·œμΉ™μ— 따라 μ²˜λ¦¬λ©λ‹ˆλ‹€.

sayGoodbye();  // TypeError: sayGoodbye is not a function

var sayGoodbye = function() {
    console.log("Goodbye, World!");
};

μœ„ μ˜ˆμ‹œλŠ” λ‹€μŒκ³Ό 같이 해석될 수 μžˆμŠ΅λ‹ˆλ‹€.

var sayGoodbye;       // λ³€μˆ˜ 선언이 ν˜Έμ΄μŠ€νŒ…λ¨
sayGoodbye();         // μ΄ˆκΈ°ν™”λ˜μ§€ μ•Šμ•˜μœΌλ―€λ‘œ TypeError λ°œμƒ
sayGoodbye = function() {
    console.log("Goodbye, World!");
};

06. μŠ€μ½”ν”„ κ΄€λ ¨ μ£Όμ˜μ‚¬ν•­βš οΈ

μžλ°”μŠ€ν¬λ¦½νŠΈμ˜ μŠ€μ½”ν”„μ™€ κ΄€λ ¨λœ μ£Όμ˜μ‚¬ν•­μ„ μ΄ν•΄ν•˜λ©΄ μ½”λ“œ μž‘μ„±κ³Ό 디버깅이 훨씬 μˆ˜μ›”ν•΄μ§‘λ‹ˆλ‹€. μŠ€μ½”ν”„μ™€ κ΄€λ ¨λœ λͺ‡ 가지 μ£Όμš” μ£Όμ˜μ‚¬ν•­μ„ μ‚΄νŽ΄λ³΄κ² μŠ΅λ‹ˆλ‹€.

1. λ³€μˆ˜ μ„ μ–Έκ³Ό μ΄ˆκΈ°ν™”μ˜ 뢄리 (var)

var ν‚€μ›Œλ“œλ₯Ό μ‚¬μš©ν•  λ•ŒλŠ” λ³€μˆ˜ μ„ μ–Έκ³Ό μ΄ˆκΈ°ν™”κ°€ λΆ„λ¦¬λ˜μ–΄ μžˆλ‹€λŠ” 점에 μ£Όμ˜ν•΄μ•Ό ν•©λ‹ˆλ‹€. 선언은 μŠ€μ½”ν”„μ˜ μ΅œμƒλ‹¨μœΌλ‘œ ν˜Έμ΄μŠ€νŒ… λ˜μ§€λ§Œ, μ΄ˆκΈ°ν™”λŠ” μ‹€μ œ μ½”λ“œ μœ„μΉ˜μ—μ„œ μ΄λ£¨μ–΄μ§‘λ‹ˆλ‹€.

console.log(a); // undefined (ν˜Έμ΄μŠ€νŒ…μœΌλ‘œ 인해 μ„ μ–Έλœ μƒνƒœ)
var a = 10;
console.log(a); // 10

μœ„ μ½”λ“œλŠ” λ‹€μŒκ³Ό 같이 해석될 수 μžˆμŠ΅λ‹ˆλ‹€.

var a;
console.log(a); // undefined
a = 10;
console.log(a); // 10

2. 블둝 μŠ€μ½”ν”„ (let, const)

letκ³Ό constλŠ” 블둝 μŠ€μ½”ν”„λ₯Ό λ”°λ₯΄λ―€λ‘œ, 이λ₯Ό μ‚¬μš©ν•  λ•ŒλŠ” 블둝 λ²”μœ„λ₯Ό λ²—μ–΄λ‚˜μ§€ μ•Šλ„λ‘ μ£Όμ˜ν•΄μ•Ό ν•©λ‹ˆλ‹€.

if (true) {
    let b = 20;
    const c = 30;
}
console.log(b); // ReferenceError: b is not defined
console.log(c); // ReferenceError: c is not defined

3. 쀑볡 μ„ μ–Έ ν”Όν•˜κΈ°

letκ³Ό constλŠ” 같은 μŠ€μ½”ν”„ λ‚΄μ—μ„œ λ™μΌν•œ λ³€μˆ˜λͺ…을 쀑볡 μ„ μ–Έν•  수 μ—†μŠ΅λ‹ˆλ‹€.

let d = 40;
let d = 50; // SyntaxError: Identifier 'd' has already been declared

const e = 60;
const e = 70; // SyntaxError: Identifier 'e' has already been declared

4. const μ‚¬μš© μ‹œ μ΄ˆκΈ°ν™” ν•„μˆ˜

const ν‚€μ›Œλ“œλŠ” μ„ μ–Έκ³Ό λ™μ‹œμ— μ΄ˆκΈ°ν™”λ₯Ό ν•΄μ•Ό ν•˜λ©°, 이후에 값을 λ³€κ²½ν•  수 μ—†μŠ΅λ‹ˆλ‹€.

const f; // SyntaxError: Missing initializer in const declaration
f = 80;

const g = 90;
g = 100; // TypeError: Assignment to constant variable.

5. ν•¨μˆ˜ μŠ€μ½”ν”„μ™€ 블둝 μŠ€μ½”ν”„

ν•¨μˆ˜ μŠ€μ½”ν”„μ™€ 블둝 μŠ€μ½”ν”„μ˜ 차이λ₯Ό μ΄ν•΄ν•˜κ³  μžˆμ–΄μ•Ό ν•©λ‹ˆλ‹€. varλŠ” ν•¨μˆ˜ μŠ€μ½”ν”„λ₯Ό λ”°λ₯΄κ³ , letκ³Ό constλŠ” 블둝 μŠ€μ½”ν”„λ₯Ό λ”°λ¦…λ‹ˆλ‹€.

function scopeTest() {
    if (true) {
        var h = 110;
        let i = 120;
    }
    console.log(h); // 110 (varλŠ” ν•¨μˆ˜ μŠ€μ½”ν”„λ₯Ό 따름)
    console.log(i); // ReferenceError: i is not defined (let은 블둝 μŠ€μ½”ν”„λ₯Ό 따름)
}
scopeTest();

6. ν΄λ‘œμ €μ™€ μŠ€μ½”ν”„

ν΄λ‘œμ €λ₯Ό μ‚¬μš©ν•  λ•Œ μ™ΈλΆ€ ν•¨μˆ˜μ˜ λ³€μˆ˜μ— μ ‘κ·Όν•  수 μžˆλ‹€λŠ” 점을 μ£Όμ˜ν•΄μ•Ό ν•©λ‹ˆλ‹€. μ΄λŠ” μ˜λ„ν•˜μ§€ μ•Šμ€ λ™μž‘μ„ μ΄ˆλž˜ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

function createCounter() {
    let count = 0;
    return function() {
        count++;
        return count;
    };
}

const counter1 = createCounter();
const counter2 = createCounter();

console.log(counter1()); // 1
console.log(counter1()); // 2
console.log(counter2()); // 1 (각 ν˜ΈμΆœμ€ λ³„λ„μ˜ ν΄λ‘œμ €λ₯Ό λ§Œλ“¦)

7. IIFE (μ¦‰μ‹œ μ‹€ν–‰ ν•¨μˆ˜ ν‘œν˜„μ‹) μ‚¬μš©

IIFEλŠ” λ³€μˆ˜λ₯Ό 블둝 μŠ€μ½”ν”„ μ•ˆμ— 가두어 μ „μ—­ λ„€μž„μŠ€νŽ˜μ΄μŠ€ μ˜€μ—Όμ„ λ°©μ§€ν•˜λŠ” 데 μœ μš©ν•©λ‹ˆλ‹€.

(function() {
    let j = 130;
    console.log(j); // 130
})();
console.log(j); // ReferenceError: j is not defined

8. ν•¨μˆ˜ λ‚΄λΆ€μ—μ„œμ˜ var

ν•¨μˆ˜ λ‚΄λΆ€μ—μ„œ varλ₯Ό μ‚¬μš©ν•  λ•ŒλŠ” ν•¨μˆ˜ 전체에 걸쳐 λ³€μˆ˜κ°€ μœ νš¨ν•˜λ‹€λŠ” 점에 μ£Όμ˜ν•΄μ•Ό ν•©λ‹ˆλ‹€. μ΄λŠ” μ˜λ„μΉ˜ μ•Šμ€ λ³€μˆ˜ μΆ©λŒμ„ μ΄ˆλž˜ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

function example() {
    for (var k = 0; k < 5; k++) {
        // do something
    }
    console.log(k); // 5 (루프가 λλ‚œ 후에도 kλŠ” μœ νš¨ν•¨)
}
example();

9. μ „μ—­ 객체와 μ•”μ‹œμ  μ „μ—­

λ³€μˆ˜λ₯Ό μ„ μ–Έν•˜μ§€ μ•Šκ³  μ‚¬μš©ν•˜λ©΄ μ „μ—­ 객체의 ν”„λ‘œνΌν‹°λ‘œ μ•”μ‹œμ  선언이 λ©λ‹ˆλ‹€. 이λ₯Ό ν”Όν•˜κΈ° μœ„ν•΄ 항상 var, let, constλ₯Ό μ‚¬μš©ν•΄ λ³€μˆ˜λ₯Ό μ„ μ–Έν•΄μ•Ό ν•©λ‹ˆλ‹€.

function implicitGlobal() {
    l = 140; // μ•”μ‹œμ  μ „μ—­ λ³€μˆ˜
}

implicitGlobal();
console.log(l); // 140 (μ „μ—­ λ³€μˆ˜λ‘œ 생성됨)
728x90
λ°˜μ‘ν˜•