- 재귀와 스택

모던JS읽으면서 생각나는 부분을 기록한 메모. 처음 읽는 사람이 같이 읽어가는 느낌으로 오면 환영. 

드디어 6장이다. 첫번째 주재로 재귀에 대해 설명을 하고 있네...

🤔 "푸로그래밍을 새롭게 학습하는 초심자가 아니라 이 주제에 익숙하다면 본 챕터를 건너뛰어도 좋습니다."

ㅋㅋㅋㅋㅋㅋ 아냐. 개인적은 생각은 매번 하는게 중요하다고 생각해... 익숙해도 해보는게 좋아ㅠㅠ

아무튼 자기자신을 재 소환하는 셀프 호출을 재귀라고 부른다.

- 두가지 사고방식

제곱을 바탕으로 설명하고 있다. a 를 2번 곱하면 제곱,  a * a * a 하면 세번 곱하니까 세제곱

pow 이란거는  power의 약어 같은데... 음.. 본문을 보면 아무튼 2 를 2 번 곱하면 4가 나올거고 2를 4번 곱하면 16이 나오는 결과를
만들려고 pow 라는 함수를 만들려고 하는 것 같다.

첫번째는 반복문으로 뺑뺑이 횟수를 채우는 것이고

두번째 예제는 스스로를 한번 결과 출력하는거 이외에는 자기 자신을 횟수(n)만큼 실행 시키는 예제이다.

n - 1 은 왜 나왔는가, 생각을 해 보면 이걸 하지 않으면 자기 자신에 빠져서 무한히 돌지 않을까 생각을 하며 아래 플로우를 보고 한번 그려보자.

n의 숫자는 1.~4. 순서대로 숫자가 줄어가며 반복을 할 것이고, 최종적으로 n == 1이 되었을 때 남은 결과를 돌려주게 된다.

처음 중첩하는 최대 개수는 재귀 깊이 라고 하고, 이 깊이는 너무 깊으면 엔진에서 제한하니 적당히 쓰자. (아, 이거때문에 가끔 브라우저 멈추면서 Maximum call stack size exceeded 났었지 ㅋㅋ)

- 실행 컨텍스트와 스택

좀 뭐라고 해야할까 중요한 내용이 나오는데...
함수 실행 절차란 무엇인가? 하면서 = (실행 컨텍스트)는 함수 실행에 대한 세부 정보를 담고 있는 내부 데이터 구조. this 값 등이 상세 실행 컨텍스트에 저장된다. 

함수가 하나 호출되면 하나의 실행 컨텍스트가 생성 되고...... 중첩 호출이 있으면....!!
현재 함수가 일시 중지되고, 실행 컨텍스트 스택에 자료구조에 쌓이고,
중첩 함수가 호출되어 실행 되고, 실행컨텍스트에 일시 중단 된 함수를 다시 꺼내와서 중단 된 함수를 실행한다.
라고 써있네... 그려보면 되는데,

생각해보자
쌓인 친구들이 실행 되었다

 

실행 종료 후(쌓인) 재귀의 깊이가 3 이었던 것을 볼 수 있다.

깊이가 너무 깊은 무한 루프를 돌면 아까 위에같은 에러 메세지가 나며 브라우저나 프로그램이 멈출 수 있다.
= 메모리사용에 유의해야한다

반복문 기반으로 하면 메모리가 절약된다는걸 보여주고 있다. 실행 컨텍스트에 사용되는 메모리가 줄어드는걸 보여준다.

마지막에는 결국 가독성이 좋은 코드와 유지보수, 성능이나 실행컨텍스트 관리 등 종합적인 관점에서 적절하게 재귀를 쓰고, 반복문을 쓰고, 해야한다고 설명 중... -ㅅ-ㅎ

- 재귀적 순회

재귀적 순회란 무엇일까? .. 재귀나 순회나 같은거 같지만 ㅎㅎ 본디 태어난 곳으로 돌아가는 뺑뺑이라.

샐러리 합을 구하는 프로그램의 예시를 보여주며, 구조를 설명하고 있다. 코드만 보면 잘 안와닿으니 밑에 설명을 같이 보면서 그림을 보며 따라가면 된다.

리듀스랑(합계산), object.values를 써서 develpment 아래에 있는 sites, internals 이외에 어떤 이름의 부서가 하위에 nested로 붙더라도 접근 할 수 있도록, 해준다.

- 연결 리스트 (링크드리스트)

빠르게 삽입 / 삭제를 해야할 때 사용하는 자료구조.

배열의 단점은 스스로가 인덱스(순번)을 가지고 있기 때문에 이걸 다 갱신해주고 바꿔줘야한다면

링크드리스트의 경우에는 너와 나 사이의 연결 고리만 끊어주면 된다.✨ 손에 손 잡고 죽 연결 되어 있다가 가운데 딱 끊고 다른 친구와 손잡으면 되는 그런 구조이다. 옆사람이 누구인지만 기억하고 있으면 되는 삽입/삭제가 편한 구조.🥺

뭐.. 자료구조는 설계에 따라 적절하게 사용해야 한다고 설명하고 있으니, 고민을 많이 해 보자. 재귀를 쓸 곳과, 반복문을 쓸 곳.

가독성을 어느정도로 올릴 까. 복잡하게 반복을 할지. 데큐를쓸지, 큐나 스택을 쓸지, 링크드리스트를 쓸지. 

개발의 설계는 다양한 길을 보여주는 것 같다.

 

- 나머지 매개변수(Rest parameters)와 전개 문법(Spread operator)

🥺자바스크립트는 역시나 구렁이 담넘어가듯 은근슬쩍 인수에 제한을 두지 않고 받으려면 다 받을 수 있는 구조를 사용 할 수 있는데, 이게 나머지 매개변수라는 부분이다.
본문의 번역과 원문을 잘 보면, Rest parameters와 Spread operator다.
그래서 한글만 적지 않고, 제목을 바꾸어 영어를 추가해서 적었다...

일단, 나머지매개변수 "..." 부분은 매개변수, 즉, 파라메터라는것을 기억하고 본문을 읽으면 이해에 도움이되고 좋을 것 같다.
본문의 내용을 따라가보면 기본적으로는, 함수에 받고자 하는 (a, b) 만 해두면 이것만 이용해 계산된다. 😰

레스트 파라메터 라고 불리는 점 세개로 불리는 ... 라는 말줄임표와 같은 이 친구의 특징은 위에서 처럼 추가로 더 넣고 싶은 경우, 가변의 인자를 넘기는 경우에 대해 지원을 할 수 있도록 도와준다. 즉, 남은 매개변수를 줍줍 주워 모아서 넘겨보내는것이 가능하다.

두번째 예시를 보자. 

...args

이것에 집중하면 된다. args 는 arguments 의 줄임말이니까 매개변수들을 모아서 함수에서 쓸 수있도록 도와준다.

특징은 맨 마지막에 있어야 하는것을 잊지 말자.

하단에 나올 친구와 약간 반대되는 속성이니 나머지 매개변수는 명시적으로 추가 파라메터들을 쓸 수 있도록 해 준다. 하고 기억하고

바로 밑에 나오는 arguments 변수 이것과 헷갈리는 경우가 있는데

- arguments 변수

분명 함수에는 아무것도 받는다고 선언 하지 않았다. 

그렇지만 본문 코드, 선언식 아래 11번째 줄, 14줄을 보면 받을 수 없는데 넘기고 있다. 과거에는 이런 식으로 그러니까 묵시적으로 넘어오면 받아서 사용 했다고 설명하고 있다.

그리고 에로우 함수는 이게 없다는걸 알아두자.

아 그리고 args(ie6도 지원) 에 와서 뒤늦게 ...(rest params..)이 비교적 최신 문법이라고 설명 하고 있는데, 이렇게 써도 될지 안될지 감이 안올때는 이 사이트를 참고하자.

rest parameters - caniuse.com/?search=Rest%20parameters

arguments - caniuse.com/?search=arguments

각 브라우저별 지원여부를 판단할 수 있다. Date relative 탭을 누르면 더 상세하다.

rest parameters 지원여부

한국의 개발자라면 ie를 미워해도 좋을듯. 그래도 나중에 보통은 babel 로 ES5 급으로 변환해서 쓸테니 괜찮을지도.

ㅠㅠ..

- Spread 문법 

아니 위에는 한글로 전개문법이라 해놓고... 밑에선 Spread 라고한다. 코드에서 뭐가 달라? 하지만 잘 보면 아차! 싶을것이다.😳

함수 선언하는 부분에 매개변수로 넣은것과 달리, 이것은 함수를 호출할 때 ... 을 넣는 문법이란 것이다. (위 그림에 아래에 해당)

arr이 인수 목록으로 알아서 길이 조절해서 최대 배열까지 Spread(좌아아악 펼치는 빵에 버터를 발라 펴듯 전개!) 된다고 한다.

배열을 받는 함수가 아니라, 인수를 받는 함수에서 이터러블한 배열을 하나하나 접근해서 풀어서 넣어야 하는 일을 줄여주었다.

Array.from 으로 유사객체를 Array 능력을 빌려와서 이터러블하게 폼에 맞춰 바꿔주는것에 대해 설명도 하고 있고..

미묘한 차이가 있다는것을 설명하고 있는데, 말을 꼬았지만, 정리하면 Spread 써야할 시점에서 DOM Element List
(<div>나 <li> 줄줄묶인 친구들)같은 유사 배열 객체를 넘겨서 처리해야하는 함수를 쓸 때 Array.from으로 하면 된다는 소리이다.

- 새 배열/객체 복사하기

지난시간에 Object.assign() 이 기억나는지 묻고있다. 전개문법(Spread)으로 같은 효과를 낼 수 있다.

상단코드는 배열

하단코드는 객체에 대해 설명하고 있는데, 

1. 상단코드 배열을 보면 2번째 줄에서 전개(Spread)로 풀어서 arrayCopy에 arr 내용을 빵에 바르는 잼처럼 푹 떠서
새로 해체해서 펴 발라 풀어 넣어주었다.
그러니 당연히 6번째 줄에서는 내부 내용을 비교하면 같은 내용이고 9번째 줄에서는 서로 다른 배열이니 틀리다고 나온다.

최종적으로 12번째에서 4를 넣어서 배열을 참조하는 메모리의 주소가 다른 것 까지 확인 사살을 하고 있다.

2. 객체도 위에랑 배열이랑 같다는 샘플 예제이다.

그렇기 때문에, 복사할객체 = Object.assign(빈 객체에, 기존객체) 가지고와서 할당하는거나,
복사해서쓸배열 = Object.assign(빈배열, 원본배열) 하는것 보다 짧게 쓸 수 있다고... 번역이 안되어있네.

2021.03.14.기준이니.. 곧 해주겠지? 라고 생각 중.

+ Recent posts