자바스크립트 테일 재귀
꼬리 재귀는 자신이 수행하는 마지막 작업을 호출하는 함수를 포함하는 프로그래밍 개념입니다. 이는 함수가 호출될 때마다 새 스택 프레임을 생성하는 대신 스택 프레임을 재사용할 수 있도록 하므로 특정 알고리즘을 최적화하는 데 유용한 기술이 될 수 있습니다.
이렇게 하면 프로그램이 사용하는 메모리 양을 줄이고 성능을 향상시킬 수 있습니다.
JavaScript에서 꼬리 재귀는 기본적으로 지원되지 않지만 다양한 기술을 사용하여 이를 달성하는 몇 가지 방법이 있습니다. 꼬리 재귀가 무엇인지, 어떻게 작동하는지, JavaScript에서 어떻게 구현하는지 자세히 살펴보겠습니다.
꼬리 재귀 사용
꼬리 재귀가 특정 상황에서 유용할 수 있는 몇 가지 이유가 있습니다.
-
메모리 효율성: 함수가 자신을 재귀적으로 호출하면 호출할 때마다 새 스택 프레임이 생성됩니다. 이는 특히 깊게 중첩된 재귀 호출의 경우 많은 메모리를 사용할 수 있습니다.
꼬리 재귀를 사용하면 함수가 스택 프레임을 재사용하여 프로그램에서 사용하는 메모리 양을 줄일 수 있습니다.
-
성능: 테일 재귀는 함수가 여러 스택 프레임을 생성하고 파괴하는 오버헤드를 피할 수 있도록 하므로 성능 측면에서도 더 효율적일 수 있습니다. 이렇게 하면 특히 입력 값이 큰 경우 함수 실행 속도가 빨라질 수 있습니다.
-
코드 단순성: 꼬리 재귀를 사용하면 명시적 루프나 반복 구조가 필요하지 않으므로 코드를 더 쉽게 이해할 수 있습니다. 이것은 코드를 더 간결하고 읽기 쉽게 만들 수 있습니다.
JavaScript에서 꼬리 재귀를 구현하는 방법
앞에서 언급했듯이 JavaScript는 기본적으로 꼬리 재귀를 지원하지 않습니다. 그러나 다양한 기술을 사용하여 이를 달성하는 몇 가지 방법이 있습니다.
예 1
한 가지 접근 방식은 함수 인수에 ES6 구문을 사용하는 것입니다. 이를 통해 함수 매개변수에 대한 기본값을 지정할 수 있습니다. 꼬리 재귀를 처리하는 간단한 래퍼 함수를 구현하는 데 사용할 수 있습니다.
function factorial(n, result = 1) {
if (n === 1) {
return result;
} else {
return factorial(n - 1, n * result);
}
}
console.log('Factorial of 5 is ' + factorial(5));
출력:
Factorial of 5 is 120
이 예에서 result
매개변수에는 1
의 기본값이 지정되어 있으므로 함수가 호출될 때 지정하지 않으면 1
로 기본 설정됩니다. 이를 통해 result
매개 변수가 1
로 설정된 factorial
을 호출하는 간단한 래퍼 함수를 생성할 수 있습니다. 이 함수는 꼬리 재귀를 처리합니다.
예 2
또 다른 접근 방식은 현재 실행 중인 함수를 참조하는 arguments.callee
속성을 사용하는 것입니다. 아래와 같이 수행하는 마지막 작업으로 자신을 호출하는 재귀 함수를 구현하는 데 사용할 수 있습니다.
function factorial(n) {
if (n === 1) {
return 1;
} else {
return n * arguments.callee(n - 1);
}
}
console.log('Factorial of 5 is ' + factorial(5));
출력:
Factorial of 5 is 120
이 접근 방식은 효과가 있지만 몇 가지 단점이 있습니다. 먼저 arguments.callee
속성은 엄격 모드에서 더 이상 사용되지 않으므로 코드에서 엄격 모드를 사용하는 경우 이를 사용하면 문제가 발생할 수 있습니다.
둘째, arguments.callee
속성을 다른 코드로 덮어쓸 수 있으며 이로 인해 예기치 않은 동작이 발생할 수 있습니다.
예 3
세 번째 접근 방식은 재귀 함수를 래핑하고 꼬리 재귀 방식으로 호출할 수 있는 고차 함수인 트램폴린
함수를 사용하는 것입니다. 트램폴린 기능을 구현하려면 다음 패턴을 사용할 수 있습니다.
function trampoline(f) {
while (f && f instanceof Function) {
f = f();
}
return f;
}
function factorial(n, result = 1) {
if (n === 1) {
return result;
} else {
return () => factorial(n - 1, n * result);
}
}
console.log('Factorial of 5 is ' + trampoline(factorial(5)));
출력:
Factorial of 5 is 120
이 예에서 factorial
함수는 꼬리 재귀 방식으로 작성되며 재귀 호출은 함수가 반환되기 전에 수행되는 마지막 작업입니다. 그런 다음 trampoline
함수는 factorial
함수를 래핑하고 재귀 호출을 처리하여 꼬리 재귀 방식으로 factorial
을 호출할 수 있도록 합니다.
트램폴린
기능을 사용하는 것은 다른 접근 방식보다 조금 더 복잡할 수 있지만 더 효율적이고 오류가 덜 발생한다는 장점이 있습니다.
I am Waqar having 5+ years of software engineering experience. I have been in the industry as a javascript web and mobile developer for 3 years working with multiple frameworks such as nodejs, react js, react native, Ionic, and angular js. After which I Switched to flutter mobile development. I have 2 years of experience building android and ios apps with flutter. For the backend, I have experience with rest APIs, Aws, and firebase. I have also written articles related to problem-solving and best practices in C, C++, Javascript, C#, and power shell.
LinkedIn