png created by here
어떤 것을 정의할 때 자기 자신을 참조하는 것
함수 실행 시 자기 자신을 다시 호출해서 코드 진행하는 함수
팩토리얼은 재귀함수의 대표적인 예시인데 나는 그것도 모르고 reduce를 사용해서 풀었다^ㅠ^
다른 분의 블로그에서 재귀함수 설명보다가 알게 되었다....
이불킥 감이므로 스스로 더 부끄러워하기 위해 박제ㄱㄱㄱ
<script>
//내가 reduce 사용해서 푼 방법
function factorial(num) {
if (num === 0) {
return 0;
}
if (num === 1) {
return 1;
}
let arr = [];
function makenArr(n) {
for (let i = 1; i < n + 1; i++) {
arr.push(i);
}
return arr;
}
return makenArr(num).reduce((누적값, 배열요소) => 누적값 * 배열요소);
}
console.log(factorial(3)); // 3*2*1 = 6
</script>
안되는 건 아니지만 코드가 길어서 비효율적이라는 걸 재귀함수 정리하면서 이해했다...
재귀함수 퀴즈면 재귀함수를 사용하는 법을 익힙시다...ㅎㅎㅎ
<script>
//재귀함수로 팩토리얼 만드는 법
function factorial(num){
if(num === 0){ //num이 0이면 바로 0 반환
return 0;
}
if(num === 1){ //num이 1이면 바로 1 반환
return 1;
}
return num * factorial(num -1);
}
console.log(factorial(3)); //6
</script>
재귀함수 factorial()
가 실행되는 과정(단순화함)
- 구해야하는 것: console.log(factorial(3))
- 실행 위해 function factorial(num){}안으로 들어감
- if(num === 0){} 읽고 n !== 0 이므로 PASS
- if(num === 1){} 읽고 n !== 1 이므로 PASS
- return num * factorial(num-1) 읽음, 3 * factorial(2) 반환됨
- 현재 구해야하는 것: console.log(factorial(3)) → console.log(3 * factorial(2))
- factorial(2)를 실행하기 위해 function factorial(num){}으로 들어감
- if(num === 0){} 읽고 n !== 0 이므로 PASS
- if(num === 1){} 읽고 n !== 1 이므로 PASS
- return num * factorial(num-1) 읽음, 2 * factorial(1) 반환됨
- 현재 상황:
console.log(factorial(3)) → console.log(3 * factorial(2)) → console.log(3 * 2 * factorial(1))
- factorial(1) 실행 위해 function factorial(num){}으로 들어감
- if(num === 1){} 읽고 n === 1 이므로 factorial(1)에 1 대입
- 현재 상황:
console.log(factorial(3))
→ console.log(3 * factorial(2))
→ console.log(3 * 2 * factorial(1))
→ console.log(3 * 2 * 1) = console.log(6); // 6
자바스크립트의 특징으로 여러 함수를 호출할 때 현재 동작 중인 함수와 그 함수 내에서 호출되는 함수, 다음에 호출할 함수 등을 나타내는 것
내가 생각하는 적절한 비유는 프링글스칩!!
프링글스칩 과자통: call Stack, 그 안에 들어있는 감자칩: function stack
사진출처: http://www.tcpschool.com/c/c_memory_stackframe
먼저 실행된 함수가 아래에 쌓이고 나중에 실행된 함수가 위에 쌓이며, 실행이 끝나면 위에서부터 차례로 stack에서 제거됨
call stack이 너무 많이 쌓이면 과부하가 일어난다.
따라서, recursion functions를 너무 많이 쓰면 call stack 과부하가 걸릴 수 있으므로 주의!!
아까 만든 factorial()을 통해 call stack이 쌓이는 과정을 녹화해보았다.
(Call Stack 부분과 Scope 부분을 유심히 볼 것!!)
call stack부분을 그림으로 나타내면
*** (anonymous) : 코드를 실행하면 기본적으로 깔리는 Stack이다.
3 * factorial(2)
을 실행한다.factorial(2) 값을 알아내기 위해 또 다른 factorial stack이 그 위에 쌓인다.
(이것이 바로 재귀함수!!)
** '두번째 factorial stack'은 factorial(3)
을 구하기 위해 읽고, '세번째 factorial stack'은 factorial(2)
을 구하기 위해 읽기 때문에 이 두개의 stack은 같지 않고 다른 것!!
factorial(){} 에서 num = 2이므로 2 * factorial(1)
을 실행한다.
6. factorial(1) 읽기를 위해 factorial(){}을 읽는다.
7. num =1, return 1;
이므로 factorial(1) = 1이다.
factorial(1)을 구했으므로 세번째에 있는 factorial stack 은 제거된다.
따라서 factorial(2) = 2 * factorial(1) = 2 * 1 = 2
가 된다.
factorial(3) = 3 * factorial(2) = 3 * 2 = 6
- 함수를 인자(argument, 함수를 호출할 때 전달되는 실제 값)로 받거나 함수를 반환하는 함수
- 함수를 일급객체로 취급하는 함수
<script>
function a(x){
return function (){};
}
a(function ex(a){
console.log(a);
});
</script>
매개변수, 전달인자 자료출처: https://wayhome25.github.io/etc/2017/12/31/parameter-argument/
- 다른 객체들에 일반적으로 적용 가능한 연산을 모두 지원하는 객체
- 인자로 넘기기, 수정하기, 변수에 대입하기와 같은 연산을 지원하고 반환 값으로 사용될 수 있을 때 일급 객체라고 한다.
(출처: 위키백과)
💛 자바스크립트에서 함수는 일급 객체이다.
적용할배열.reduce(콜백함수[, 초기값]);//초기값은 선택사항
//더 풀어서 쓰면
적용할배열.reduce((누적값, 배열내데이터) => 연산식)
아까 팩토리얼 풀 때 reduce 문법이 헷갈렸기 때문에 다시 정리!!!
reduce는 배열 안에 있는 각각의 데이터를 하나씩 꺼내서 연산을 하고 하나의 누적 연산값을 반환한다.
보통 배열 안의 데이터로 사칙연산할 때 많이 쓴다.
아까 팩토리얼에서 쓴 reduce를 다시 가져와보면
<script>
function factorial(num) {
if (num === 0) {
return 0;
}
if (num === 1) {
return 1;
}
let arr = [];
function makenArr(n) {
for (let i = 1; i < n + 1; i++) {
arr.push(i);
}
return arr;
}
return makenArr(num).reduce((누적값, 배열요소) => 누적값 * 배열요소);
}
console.log(factorial(3));
</script>
num = 3이므로 arr = [1,2,3]
이다.
arr과 reduce만 따로 가져와서 다시 보면
<script>
makenArr(3) = [1,2,3]
makenArr(3).reduce((누적값, 배열요소) => 누적값 * 배열요소);
//1 * 2 = 2(누적값)
//2(누적값) * 3(다음 배열요소) = 6
</script>
배열의 모든 값을 순환 후 새로운 배열을 반환하기 위해 사용
배열.map(callback(current value, index, source), this)
- current value : 현재 반환할 값
- index: 현재 해당하는 인덱스의 값
- source: 순회하는 대상 객체
- this: 사용할 this 키워드의 값
* this 변경시에는 화살표 함수로 표시 불가능
let arr = [1,2,3]
let result = arr.map((num) => num + 1);
console.log(result);//[2,3,4]
<문법 자료 출처>