“Uncaught RangeError: Maximum call stack size exceeded” 오류 이해하기
이 오류는 JavaScript에서 함수가 자기 자신을 너무 많이 호출하여 스택 오버플로가 발생할 때 나타난다. 콜 스택(Call Stack)은 인터프리터가 여러 함수를 호출하는 스크립트에서 현재 위치를 추적하는 메커니즘이다. 스택의 크기에는 제한이 있으며, 이 한도를 초과하면 오류가 발생한다.
주요 원인: 무한 재귀
가장 흔한 원인은 무한 재귀(infinite recursion)다. 이는 함수가 적절한 종료 조건 없이 자기 자신을 계속 호출하는 경우에 발생한다.
문제 코드:
function infiniteLoop() {
infiniteLoop(); // 함수가 멈추는 조건 없이 자신을 호출한다.
}
// 이 함수를 호출하면 오류가 발생한다.
// infiniteLoop();
또 다른 일반적인 시나리오는 기본 케이스(base case)는 있지만, 재귀 호출이 입력을 기본 케이스로 유도하지 못하는 경우다.
function countdown(n) {
if (n === 0) {
console.log("Blast off!");
return;
}
console.log(n);
countdown(n + 1); // 실수! 0이라는 기본 케이스에서 멀어지게 숫자를 증가시킨다.
}
// countdown(10);
오류 해결 방법
1. 기본 케이스(종료 조건) 추가하기
재귀 함수는 반드시 재귀를 멈추는 조건인 기본 케이스(base case)를 가져야 한다.
잘못된 코드 (기본 케이스 없음):
function goOnForever() {
goOnForever();
}
해결책: 조건이 충족되면 함수가 자신을 다시 호출하지 않도록 하는 조건을 만들어야 한다.
function countdown(n) {
if (n <= 0) { // 기본 케이스
console.log("Done!");
return;
}
console.log(n);
countdown(n - 1); // 기본 케이스를 향해 가는 재귀 호출
}
countdown(5); // 5, 4, 3, 2, 1, Done!
2. 반복적 접근 방식으로 변환하기
재귀적 해결책이 무한이 아니더라도 너무 깊으면 스택 크기를 초과할 수 있다. 이런 경우 함수를 루프(반복적 접근 방식)를 사용하도록 변환하면 문제를 해결할 수 있다.
재귀 함수:
function sumRecursive(n, total = 0) {
if (n <= 0) {
return total;
}
return sumRecursive(n - 1, total + n);
}
반복적 해결책:
function sumIterative(n) {
let total = 0;
for (let i = 1; i <= n; i++) {
total += i;
}
return total;
}
// 이 함수는 스택 오버플로 없이 매우 큰 숫자도 처리할 수 있다.
console.log(sumIterative(100000));
재귀를 신중하게 관리하고 모든 재귀 함수에 도달 가능한 기본 케이스가 있도록 보장함으로써 “Maximum call stack size exceeded” 오류를 피하고 더 안정적인 코드를 작성할 수 있다.
Leave a comment