๐[JavaScipt ์๊ณ ๋ฆฌ์ฆ & ์๋ฃ๊ตฌ์กฐ ๋ง์คํฐํด๋์ค ์์
] ์ ์ ๊ณต ๋ฐ์ ์๊ณ ๋ฆฌ์ฆ ๊ณต๋ถ๋ฅผ ํ๊ณ ์๋๋ฐ์!
์ ๋ฐ๋ฏธ์ ๊ฐ์ ์ธ ์งฑ์งฑํ ํ๋ก๋ชจ์
๊ธฐ๊ฐ์ด ์์ผ๋! ๊ผญ ์ฐฉํ ๊ฐ๊ฒฉ์ ์์ฐฌ ๊ฐ์ ์๊ฒจ๊ฐ์๊ธธ ๋ฐ๋ผ์
a propcess (a function in out cas) that calls itself
์๊ธฐ ์์ ์ ํธ์ถํ๋ ํจ์
์๋ฐ์คํฌ๋ฆฝํธ์ ๊ฐ์ ํ๋ก๊ทธ๋๋ฐ ์ธ์ด์๋ ํจ์ ํธ์ถ์ ์ ๋ฆฌํ๊ณ ๋ด๋นํ๋ ๋ฐ์ดํฐ ๊ตฌ์กฐ(data structure)๊ฐ ์๋ค. ์ด๊ฒ์ call stack
์ด๋ผ๊ณ ํ๋ค.
ํธ์ถ ์คํ์ ์๋ฐ์คํฌ๋ฆฝ์ ๋ณด์ด์ง ์์ ๊ณณ์์ ์๋ํ๋ ์ ์ ๋ฐ์ดํฐ ๊ตฌ์กฐ(static data structure)์ด๋ค.
stack ๋งจ ์์ ํจ์๋ฅผ ์คํํ๊ณ , ๋ฆฌํด์ ํ์ธํ ๋ค, ์ปดํ์ผ๋ฌ๊ฐ ์คํ์ ์ ์ผ ์์ ์๋ ํจ์๋ฅผ ์ ๊ฑฐํ๋ค.
๊ธฐ๋ณธ์ ์ธ ๊ฐ๋ ์ ๋์ผํ ํจ์๋ฅผ ๋ฐ๋ณต์ ์ผ๋ก ํธ์ถํ๋ ๊ฒ์ด๋ค. ํ์ง๋ง ์์ํ ๋ฐ๋ณตํ๋ค๋ฉด ๊ณผ๋ถํ๊ฐ ์ผ์ด๋๊ณ ํ๋์จ์ด์ ํฐ ์ ์ํฅ์ ๋ผ์น ๊ฒ์ด๋ค. ๊ทธ๋์ ์ฌ๊ทํจ์๋ base case์ฆ, ์ข ๋ฃ ์กฐ๊ฑด์ด ์์ด์ผ ํ๋ค.
//์ฌ๊ท๋ฅผ ์ฌ์ฉํ ๊ฒฝ์ฐ
function sayHello(num){
if(num <= 0){ //end point
console.log('Hello');
return; // returnํ๋ ๊ฒ์ด ์๋๋ผ๋ ๊ผญ return์ ํด์ค์ผ ํจ
}
console.log(num)
num--;
sayHello(num);
}
//๋ฐ๋ณต๋ฌธ์ ์ฌ์ฉํ ๊ฒฝ์ฐ
function sayHello(num){
for(let i = num; i > 0; i--){
console.log(i);
}
console.log('Hello')
}
sayHello(3)
์์ ์์์์ ์ฌ๊ท ํจ์์ ๊ฒฝ์ฐ,
sayHello(0)
๊ฐ ๋๋ฉด num <= 0
์ด ๋์ด console.log('Hello')
๊ฐ ์๋ํ๋ค. ์ด๊ฒ์ด ๋ฐ๋ก ์ข
๋ฃ ์กฐ๊ฑด์ด๋ค.
return
ํด์ฃผ๋ ๊ฒ์ด ์๋๋ผ ํ๋๋ผ๋ ์ฌ๊ท ํจ์๋ฅผ ์ฌ์ฉํ ๋, ์ข
๋ฃ ์กฐ๊ฑด ์์๋ ๊ผญ! return์ ํฌํจํด์ฃผ์ด์ผ ํ๋ค.
๋ง์ฝ ๋ฆฌํด๋ฌธ์ด ์๋ค๋ฉด ์ปดํ์ผ๋ฌ๊ฐ ํจ์๋ฅผ ์ ๊ฑฐํ์ง ์๊ณ ๊ณ์ ์งํ๋ ๊ฒ์ด๋ค.
function mul(num){
if (num === 1) return 1; // num === 1 ์ base case
return num * mul(num-1);
}
์์ ์ฝ๋๋ฅผ ์ดํด๋ณด์
mul(5)๋ฅผ ์คํํ๋ค๋ฉด
mul(5) = 5*mul(4)
mul(4) = 4*mul(3)
mul(3) = 3*mul(2)
mul(2) = 2*mul(1)
mul(1) = 1
๋ฐ๋ผ์ ์์ ํจ์๋ num๋งํผ์ ์ซ์๋ฅผ ๋ชจ๋ ๊ณฑํ ๊ฐ์ ๋ฆฌํดํ๋ค.
//๋ฐ๋ณต ํจ์๋ก ๊ตฌํ
function factorial(n){
const result = 1;
for( let i = n; i > 1; i-- ){
result *= i
}
return result;
}
์์ ํฉํ ๋ฆฌ์ผ์ ๋ฐ๋ณต๋ฌธ์ผ๋ก ๊ตฌํํ ํจ์๋ฅผ ์ฌ๊ท๋ก ๊ตฌํํด๋ณด๋๋ก ํ์.
//์ฌ๊ท๋ก ๊ตฌํ - **๋ฌดํ๋ฐ๋ณต ์๋ฌ**
function factorial(n){
return n * factorial(n-1)
}
์์ ์ฝ๋๋ ์๋ํฌ์ธํธ, ์ข
๋ฃ์ง์ ์ด ์๋ค. ๋ฌดํ ๋ฐ๋ณต์ด ๋ ์ ๋ฐ์ ์๋ค.
์คํ์ ๋ฌดํ์ผ๋ก ํจ์๊ฐ ์์ด๋ ๊ฒ์ด๋ค. ๊ทธ๋ฌ๋ฉด ์ต๋ ํธ์ถ ์คํ์ ์ด๊ณผํ๋ค๋ ์๋ฌ๊ฐ ๋ ์ ์๊ณ ์ด๋ฅผ stack overflow
๋ผ๊ณ ํ๋ค.
//์ฌ๊ท๋ก ๊ตฌํ
function factorial(n){
if(n===1) return 1;
return n * factorial(n-1)
}
์ด๋ ๊ฒ ์๋ ํฌ์ธํธ๋ฅผ ๊ฑธ์ด์ฃผ๋ฉด ๋ฌดํ ๋ฐ๋ณตํ์ง ์๋ ์ฝ๋๋ฅผ ๊ตฌํํ ์ ์๋ค.
์ง๊ธ๊น์ง ๊ตฌํํ ์ฌ๊ท ํจ์๋ ๋จ์ผ ๋จ๋ ํจ์(single standalone function) ์ด๋ค. ์ธ๋ถ์์ ํฉํ ๋ฆฌ์ผ ํจ์๋ฅผ ํธ์ถํ๋ฉด ํฉํ ๋ฆฌ์ผ ํจ์๋ ์ง์ ์์ฒด ์ฝ๋ ๋ด์ ํฉํ ๋ฆฌ์ผ ํจ์๋ฅผ ํธ์ถํ๋ค. ํ์ง๋ง helper method ์ฌ๊ท๋ ๋จ๋ ํจ์์ ์กฐ๊ธ ๋ค๋ฅด๋ค.
ํฌํผ ๋ฉ์๋ ์ฌ๊ท์ ๊ธฐ๋ณธ ํํ๋ ๋ค์๊ณผ ๊ฐ๋ค.
์ธ๋ถ ํจ์ ๋ด์ ์ฌ๊ท ํจ์๊ฐ ๋ค์ด์๋ค.
//์ธ๋ถํจ์
function outer(input){
let outerScopeVariable = []
//์ฌ๊ทํจ์
function helperRecursion(helperInput){
helperRecursion(helperInput--)
}
helper(input)
return outerScopedVariable;
}
๋ฐฐ์ด์ด๋ ๋ฐ์ดํฐ ๋ชฉ๋ก ๊ฐ์ ๊ฒ์ ์ปดํ์ผ ํด์ผ ํ ๋ ํฌํฐ ๋ฉ์๋ ์ฌ๊ท๋ฅผ ์ฌ์ฉํ๋ค. recursive helper๋ฅผ ์ฌ์ฉํ๋ฉด ๋น ๋ฐฐ์ด์ ์์งํด์ผ ํ๋ ๋ฐ์ดํฐ๋ค์ ์ ์ฅํ๊ธฐ์ ์ฉ์ดํ๋ค.
๋ง์ฝ ์ฌ๊ท ํจ์ ์์ฒด์์ ๋ฐฐ์ด ๋ณ์๋ฅผ ์ ์ธํ๊ฒ ๋๋ค๋ฉด ํจ์๋ฅผ ํธ์ถํ ๋๋ง๋ค ๋ฐฐ์ด ๊ฐ์ด ๋ฆฌ์ ๋ ๊ฒ์ด๋ค.
function collectNums(arr){
let result = []; //ํธ์ถ ํ ๋ ๋ง๋ค ์ฌ์ ์๋จ
if(arr.length === 0){
return;
}
...
}
์์ ์ฝ๋๋ฅผ ํฌํผ ์ฌ๊ท๋ก ์์ ํด๋ณด์.
function collectNums(arr){
let result=[]
//ํฌํผ์ฌ๊ท
function helperEvens(helperInput){
//end point ์ข
๋ฃ ์กฐ๊ฑด
if(helperInput.length === 0){
return;
}
if(helperInput[0] % 2 == 0){
result.push(helperInput[0])
}
helperEvens(helperInput.slice(1))
}
helperEvens(arr)
return result;
}
collectNums([1,2,3,4,5])
collectNums([1,2,3,4,5])
์ collectNums
๋ฅผ ํธ์ถํ๋ค.collectNums
์์ ์๋ helperEvens([1,2,3,4,5])
๊ฐ ํธ์ถ๋๋ค.[1,2,3,4,5]
์ ๊ธธ์ด๊ฐ 0์ด ์๋๊ธฐ ๋๋ฌธ์ ์ข
๋ฃ ์กฐ๊ฑด์ ํจ์คํ๋ค. if(helperInput[0] % 2 == 0)
๋ฅผ ๋ณด๋ฉด, helperInput[0]
์ธ arr์ ์ธ๋ฑ์ค 0์ธ 1์ 2๋ก ๋๋ ์ง์ง ์๊ธฐ ๋๋ฌธ์ ๋ ํจ์คํ๋ค. helperInput.slice(1)
= [2,3,4,5]
์ด๋ฏ๋ก helperEvens(helperInput.slice(1))
์ ์ํด helperEvens([2,3,4,5])
๋ฅผ ์คํํ๋ค.if๋ฌธ
์์ helperInput
๋ฐฐ์ด์ ์ธ๋ฑ์ค 0์ธ 2๋ result
์ push๋๋ค. ๊ทธ๋ฆฌ๊ณ ๋ slice๋ก ์ธ๋ฑ์ค 0์ ์๋ผ๋ด๊ณ ๊ทธ ๋ค์ ์์๋ค์ ์ฌ๊ท๋ฅผ ํตํด ์ง์ํ๋ณ์ ํ๋ค.helperInput
์ ๊ธธ์ด๊ฐ 0์ด ๋๋ฉด ๋ฐฐ์ด result
์๋ ์ง์๋ง ๋จ๊ฒ ๋๊ณ return
๋๋ค.์์ ์ฌ๊ท ํจ์๋ ํจ์์ ๋ชจ๋ ์ฝ๋๋ฅผ ํฌํจํ๊ณ ์ฌ๊ท์ ์ผ๋ก ์๋ํ๋๋ก ํ๋ ๊ฒ์ด๋ค. ํฌํผ ์ฌ๊ท์ ๋ฌ๋ฆฌ ์ธ๋ถ ํจ์, ๋ด๋ถ ํจ์๋ฅผ ๊ตฌ๋ถ ์ง์ด ์ค์ฒฉ ํจ์๋ก ์์ฑํ๋ ๊ฒ์ด ์๋๋ผ ํ๋์ ํจ์๋ก ์์ฑํ๋ ๊ฒ์ด๋ค.
function collectEven(arr){
let result = [];
if(arr.length === 0){
return result;
}
if(arr[0] % 2 === 0){
result.push(arr[0]);
}
result = result.concat(collectEven(arr.slice(1)));
return result;
}
collectEven([1,2,3,4,5])
collectEven([1,2,3,4,5])
๋ฅผ ํ๋ฉด, ์ฒซ ์กฐ๊ฑด๋ฌธ์์ ๊ธธ์ด๊ฐ 0์ด ์๋๊ธฐ ๋๋ฌธ์ ์ด ์กฐ๊ฑด๋ฌธ์ ํจ์คํ๋ค. ๋ ๋ฒ์งธ ์กฐ๊ฑด๋ฌธ์์๋ arr[0]์ด 2๋ก ๋๋์์ ๋ ๋๋จธ์ง๊ฐ 0์ด ์๋๊ธฐ ๋๋ฌธ์ ํจ์คํ๋ค. arr1.concat(arr2)
์ arr1๊ณผ arr2๋ฅผ ํฉํ์ฌ ์๋ก์ด ๋ฐฐ์ด์ ๋ฐํํ๋ค.result = result.concat(collectEven(arr.slice(1)));
์์ arr.slice(1)
๋ [2,3,4,5]
์ด๋ค.collectEven(arr.slice(1))
์ผ๋ก ํจ์๋ฅผ ์ฌ๊ท์ ์ผ๋ก ํธ์ถํ๊ธฐ์ ์งํํ๋ค.collectEven([2,3,4,5])
์์ result์ 2๊ฐ ๋ค์ด๊ฐ๋ค.[2].concat(collectEven([3,4,5]));
์ด ๋๊ณ ์ด๋ฅผ ์์ธํ ๋ํ๋ด๋ณด์๋ฉด collectEven([1,2,3,4,5])
[].concat(collectEven([2,3,4,5]))
[2].concat(collectEven([3,4,5]))
[].concat(collectEven([4,5]))
[4].concat(collectEven([5]))
[].concat(collectEven([]))
[]
๊ฑฐ์ฌ๋ฌ ์ฌ๋ผ๊ฐ ๋ณด๋ฉด์ ํธ์ถ๋๋ ๊ฐ๋ค์ ํ์ธํ์๋ฉด
[]
[].concat(collectEven([])) //collectEven([]) = [] => [].concat([])
[4].concat(collectEven([5])) //[4].concat([])
[].concat(collectEven([4,5])) //[].concat([4])
[2].concat(collectEven([3,4,5])) //[2].concat{[4])
[].concat(collectEven([2,3,4,5])) //[].concat([2,4])
collectEven([1,2,3,4,5])
๋ฆฌํด๊ฐ์ `[2,4]` ๋ก ์ง์๋ง ํธ์ฌ๋ ๋ฐฐ์ด์ด ๋ง๋ค์ด์ง๋ค.
slice
the spread operator
concat
๊ฐ์ ๋ฉ์๋๋ฅผ ํ์ฉํ๋ฉด ์๋ก์ด ๋ฐฐ์ด์ ๋ง๋ค์ด ๋ฐํํ๊ธฐ ๋๋ฌธ์ ๋ฐฐ์ด ์์ฒด๋ฅผ ๋ณ๊ฒฝํ ํ์๊ฐ ์๋ค.immutable
ํ๋ค. ๋ณ๊ฒฝ, ์์ ์ด ๋ถ๊ฐํ๊ธฐ ๋๋ฌธ์ slice
substr
๋ฑ์ ํตํด ๋ณต์ฌ๋ณธ์ผ๋ก ํ์ฉํ๋ ๊ฒ์ด ์ข๋ค.Object.assign
์ด๋ the spread operator
์ฐ์ฐ์๋ฅผ ์ฌ์ฉํ์ฌ ๋ฅํ ๋ณต์ฌ๋ฅผ ํ๋ ๊ฒ์ด ์๋ณธ์ ๋ฐฉํดํ์ง ์๊ธฐ์ ์ข๋ค.์ด ๊ฐ์์ ์ฅ์ ์ ์ด๋ ๊ฒ ๊ณผ์ ๋ฅผ ์ ๊ณตํ๋ค๋ ์ ์ด์์!
์น์ 8์ ์ฌ๊ท๋ฌธ์ ์งํฉ์ด๊ณ ๋ ์ฐ์ตํด๋ณด๊ณ ์ถ์ ์ฌ๋๋ค์ ์ํด ์น์ 9 ๋ณด๋์ค ๋์ ์ฌ๊ท ๋ฌธ์ ๊น์ง ์๋ต๋๋ค!
์์ฝ๊ฒ๋ ๋ฌธ์ ์งํฉ ์น์
์ ์ฌ๊ท๊น์ง๋ง ์์ด์.
์๋ฌด๋๋ ๊ธฐ์ด๋ฅผ ๋ค์ก๊ณ ์ ํ๋ ๊ฒ์ ๋ชฉ์ ์ด ์๋ ๊ฐ์์ด๋ค ๋ณด๋ ๊ณผ์ ๊ฐ ๋ชจ๋ ๊ฐ๋
๋ค์ ์ ๊ณต๋์ง ์์ต๋๋ค!
๊ทธ๋์ ์ ๋ฐ๋ฏธ [JavaScript ์๊ณ ๋ฆฌ์ฆ & ์๋ฃ๊ตฌ์กฐ ๋ง์คํฐํด๋์ค] ๋ก ๊ฐ๋ ์ ๋ค์ก๊ณ ๋ฐฑ์ค์ผ๋ก ํด๋น ๊ฐ๋ ์ํ ์ถ๊ฐ์ ์ธ ๋ฌธ์ ๋ฅผ ํ์ด๋ณด๋ ๊ฒ์ด ๊ฐ์ฅ ๋ฒ ์คํธ๋ผ๊ณ ์๊ฐํฉ๋๋ค!