SUB ROUTINE CHAIN
- Js는 함수 호출 시 인자와 지역변수가 만들어지고 이를 실행컨텍스트라고 한다.
- Sub routine이 중첩된 경우 CALL STACK이 계속 쌓임 ~ 실행컨텍스트가 쌓인다.
TAIL RECURSION
언어 엔진이 return 포인트 지정을 제공한다면, 중첩 함수의 콜스택을 해제 할 수 있다.
(제어문 처럼 loop에 대한 stack 클리어 가능)
const sum = v => v + (v > 1 ? sum(v - 1): 0);
- 위 코드는 연산자 +로 인해 TAIL RECURSION을 방해한다. ~ stack memory 유발
const sum = (v, prev = 0) => {
prev += v;
return (v > 1 ? sum(v - 1, prev) : prev);
};
- 위 코드는 합계를 인자로 보냄으로써 TAIL RECURSION 가능
- 삼항연산자는 언어스펙 정의에 따라 && || 연산자와 함께 stack memory를 일으키지 않는다.
const sum = (v) => {
let prev = 0
while(v > 1){
prev += v;
v--;
}
}
- TAIL RECURSION 함수는 기계적으로 Loop문으로 바꿀 수 있다.
CLOSURE
RUNTIME STATE
- JS는 Routine을 값으로 만들어서, runtime 동안 routine을 만들거나 해제한다.
- JS함수는 글로벌 변수 뿐만 아니라 FLOW상의 변수도 인식할 수 있다. ~ 자유변수(free varables)
- 자유 변수들이 routine에서 참조되면 routine이 끝나기 전까지 해제 되지않는다 ~ closure
NESTED COLOSURE
- JS에서는 블록을 생성할때 마다 중첩된 CLOUSRE 생성된다.
SHADOWING
- 자유변수 참조 시 가장 가까운 자유변수를 참조하게 됨
- SHADOWING을 통해 중첩된 CLOSURE에서 바깥쪽에 있는 동일한 이름의 변수를 보호할 수 있다.
CO ROUTINE
- routine은 호출하면 flow을 지나고 retrun 한다. ~ routine이 한번에 끝나는 것을 보장
- co routine에서는 return이 아닌 yield를 사용하고, flow가 진행하다가 서스펜션이 걸리고 복귀한다. 다시 호출 하면 서스펜션이 걸린 곳부터 다시 시작한다.
- co routine의 장점은 routine의 지역변수가 해제되지 않으므로 상태관리 용이
const generator = function*(a) {
a++;
yield a;
a++;
yield a;
a++;
yield a;
}
const coroutine = generator(3);
let result = 0;
result += coroutine.next().value;
console.log(result)
result += coroutine.next().value;
console.log(result)
result += coroutine.next().value;
console.log(result)