hanker

JavaScript - 스코프(Scope)와 클로저(Closure) 본문

JavaScript

JavaScript - 스코프(Scope)와 클로저(Closure)

hanker 2024. 12. 27. 00:00
반응형

이번 글에서는 JavaScript에서 중요한 개념인 스코프와 클로저에 관해 알아보자

 


1. 스코프(Scope)

 

1-1. 스코프란?

스코프는 변수와 함수에 접근할 수 있는 유효 범위를 의미한다. 

즉, 변수가 어디에서 선언되고, 어디에서 사용할 수 있는지를 결정한다.

 

 

1-2. 스코프의 종류

 

  • 전역 스코프 (Global Scope)
    • 모든 코드에서 접근 가능한 변수
    • 함수나 블록 밖에서 선언된 변수는 전역 변수로 취급된다.
let globalVar = "Hanker!";

function printGlobalVar() {
    console.log(globalVar); // "Hanker!"
}
printGlobalVar();

 

  • 전역 스코프 (Global Scope)
    • 함수 내부에서 선언된 변수는 해당 함수 안에서만 접근 가능
function exampleFunction() {
    let localVar = "I am Hanker!";
    console.log(localVar); // "I am Hanker!"
}
exampleFunction();
console.log(localVar); // ReferenceError: localVar is not defined

 

 

  • 블록 스코프 (Block Scope)
    • ES6에서 도입된 let과 const로 선언된 변수는 블록 {} 내부에서만 유효하다.
{
    let blockVar = "I am block-scoped";
    console.log(blockVar); // "I am block-scoped"
}
console.log(blockVar); // ReferenceError: blockVar is not defined

 

 

1-3. 스코프 체인

스코프 체인은 JavaScript가 변수를 찾는 과정을 설명한다.

특정 변수를 찾을 때, 현재 스코프에서 시작하여 부모 스코프를 따라가며 변수를 검색한다.

let outerVar = "I am outer";

function innerFunction() {
    console.log(outerVar); // "I am outer"
}

innerFunction();

 


2. 클로저(Closure)

 

 

2-1. 클로저란?

클로저는 함수와 함수가 선언될 당시의 렉시컬 스코프를 기억하는 기능이다.

즉, 함수가 외부 스코프의 변수에 접근할 수 있는 능력을 말한다.

 

 

2-2. 클로저의 동작 원리

클로저는 함수 내부에서 외부 함수의 변수를 계속 참조할 수 있을 때 생성된다.

function outerFunction() {
    let outerVar = "outer";

    function innerFunction() {
        console.log(outerVar); // "outer"
    }

    return innerFunction;
}

const closureFunc = outerFunction();
closureFunc(); // "outer"

 

2-3. 클로저의 특징

  • 클로저는 외부 함수가 종료된 이후에도 변수에 접근할 수 있다.
  • 클로저는 상태를 유지하는 데 유용하다.

 


3. 클로저의 실용 예제

 

3-1. 데이터 보호(캡슐화)

클로저를 사용하면 변수를 외부에서 직접 접근하지 못하도록 보호할 수 있다.

function counter() {
    let count = 0;

    return function () {
        count++;
        return count;
    };
}

const increment = counter();
console.log(increment()); // 1
console.log(increment()); // 2
console.log(increment()); // 3

 

 

3-2. 함수 팩토리

클로저를 사용하면 동적으로 커스터마이징된 함수를 생성할 수 있다.

function multiplier(factor) {
    return function (number) {
        return number * factor;
    };
}

const double = multiplier(2);
console.log(double(5)); // 10

const triple = multiplier(3);
console.log(triple(5)); // 15

 

3-3. 비동기 코드에서 상태 유지

클로저는 비동기 코드에서 유용하게 사용된다.

function createTimeoutLogger() {
    for (let i = 1; i <= 3; i++) {
        setTimeout(function () {
            console.log(i); // 1, 2, 3
        }, i * 1000);
    }
}

createTimeoutLogger();


4. 클로저 사용 시 주의점

 

4-1. 메모리 누수

  • 클로저가 불필요하게 많은 변수를 유지하면 메모리 누수가 발생할 수 있다.
  • 사용하지 않는 클로저는 적시에 제거해야 한다.

 

4-2. 의도치 않은 변수 공유

  • 반복문에서 클로저를 사용할 때 주의해야 한다.
for (var i = 1; i <= 3; i++) {
    setTimeout(function () {
        console.log(i); // 4, 4, 4 (예상과 다른 결과)
    }, i * 1000);
}

// let을 사용하여 해결
for (let i = 1; i <= 3; i++) {
    setTimeout(function () {
        console.log(i); // 1, 2, 3
    }, i * 1000);
}

 


5. 정리

 

- 스코프(Scope)는 변수의 유효 범위를 결정한다.

- 클로저(Closure)는 함수가 외부 스코프의 변수를 기억하고 참조할 수 있는 기능이다.

 

 

반응형