클로저(Closure)

✒️ 2025-05-23 15:07 내용 수정


참고 자료 : mdn web docs closures, inpa tistory 클로저, poiemaweb 클로저

주변 상태에 대한 참조와 함께 묶인 함수의 조합


형태

// 변수를 반환할 때
function test() {
	let param = '';
	return param;
}

// 함수를 반환할 때
function test2() { // 여기는 외부 함수
	var name = "tester"; // 외부 함수의 변수
	return function () { // 여기가 내부 함수, 그리고 클로저
		console.log(name); // 클로저는 외부 변수를 기억
	}
}

특징

function test() {
	let param = 10; // test의 지역 변수
	function fn() { // 내부 함수, 클로저
		console.log(param); // 부모 함수의 변수를 사용
	}
	return fn;
}

let newFn = test();
newFn(); // 10
console.log(param); // Uncaught ReferenceError: param is not defined
// fn은 param에 접근할 수 있지만, 외부에선 param에 직접 접근할 수 없다.
function counter() {
	var count = 0;

	// 클로저는 자신이 선언된 환경을 기억!
	function countUp() { // 클로저
		count++;
		console.log(count);
	}

	return countUp;
}

// counter는 내부 함수를 반환하고 
// 실행 컨텍스트에서 제거됨
// myFunc에는 반환된 내부 함수가 countUp이 담긴다
const myFunc = counter();

// 클로저는 선언된 환경을 기억
// 외부 함수의 스코프였던 count에 대한 기억을 가지고 있다
myFunc(); // 1
myFunc(); // 2
myFunc(); // 3
function createUser(email, birth) {
    let _email = email; // 함수 내에 선언된 지역함수는 private

    const user = {
        birth,
        get email() {
            return _email;
        },
        set email(address) {
            _email = address;
        }
    }

    return user;
}

let user001 = createUser('bbbbbb', '19981024');

console.log(user001._email); // undefined
console.log(user001.email); // bbbbbb

user001.email = 'cccccc'; // set에 바인딩 된 함수로 _email에 접근
console.log(user001.email); // cccccc

user001._email = 'ddddddd'; // 직접 접근하려 한다면 값이 바뀌지 않는다
console.log(user001.email);  // cccccc