본문 바로가기
개발자 도전기/[STUDY] JS || TS

JavaScript | FP && ES6+ | 함수형 자바스크립트 기본기

by 답수 2022. 1. 19.
728x90
SMALL

 

 

흠. 어쩌다 JS 언어를 계속 파게 되었을까. 일단 정글 나만의무기 프로젝트를 할 때 node.js를 선택한 것이 시작이었다.

 

그럼 왜 node.js를 선택했을까?

 

프로젝트를 진행하는 기간이 5주(실제 개발은 3주도 안 됨..)도 되지 않는 짧은 시간이다 보니 언어를 학습하는 것 까지 포함해서 빠른 개발과 테스트, 사용자 피드백 주기를 고려했을 때 그나마 익숙하고 커뮤니티가 큰 언어 JS기반인 node.js가 적합하다고 생각했다.

(nodeJS가 쉽다는 것이 아니라 팀원 모두 자바스크립트를 사용한 경험이 있고, socket.io 등의 실용적인 라이브러리를 빨리 배우고 사용할 수 있기 때문)

 

여하튼! 프로젝트 때 express 프레임워크로 서버를 구축하고 여러 api를 만들어 보면서 어느 정도는 자바스크립트에 대해 알게 되었다!라고 생각했지만, 정글 수료 이후 취업 준비를 하면서 내가 알던 것들이 껍데기에 불과했다는 것을 느꼈다.

 

프로젝트를 하면서 여러 코드를 작성해봤지만, 결국 내 것으로 제대로 만든 코드가 아닌, 그저 프로젝트를 빨리 완성시키기 위해 실행만 되면 Okay! 식으로 빨리 복붙 하면서 넘겨짚은 개념들이 너무 많았다.

 

실제로 면접을 볼 때에도 '함수형 프로그래밍이 뭐냐?', '객체 지향 프로그래밍은?' 이런 질문들을 받았을 때, 명확하게 답을 할 수 없었다. 즉, 알맹이가 없다는 거다.

 

지금 정리하는 이 글의 시리즈는 인프런의 함수형 프로그래밍과 JavaScript ES6+ 를 기반으로 알맹이를 채우기 위한 공부 로그가 될 것이다. 강의를 들으면서 개념을 이해하고 머릿속에 넣는 것뿐만 아니라, 조금이라도 모호하고 헷갈리는 부분이 발생하면 놓치지 않고 하나씩 다 챙겨보려고 한다. 그리고 FP와 OOP 개념을 확실하게 익혀서 앞으로의 코드 작성에 조금은 더 퀄리티가 높아지길 바라면서 공부할 것이다.

 

 

함수형 자바스크립트 기본기

자만 떨지 말고 기초부터 다시 차근차근 공부하고 기록하자!

 

자! 그래서! 함수형 프로그래밍(Functional Programming)이 뭔데? 

FP는 객체지향 프로그래밍(Object-Oriented Programming)과는 다르다. OOP는 말 그대로 객체를 기반으로 데이터 처리 등의 프로그래밍을 말한다. 그럼 FP는? 역시 함수를 기반으로 한 프로그래밍이겠지...? 함수형 프로그래밍은 유지 보수가 용이한 코드를 작성하는데 효과적이며 현재 소프트웨어 추세라고 한다. 그 특징으로는 순수 함수(입출력이 순수 - 하나 이상의 인자를 받고, 받은 인자를 처리하여 리턴), 불변성(원본 데이터는 불변) 등 여러 특성들이 있다. 더 자세한 것은 강의를 정리하면서 익혀 가자구

 

 

자바스크립트는 일급 함수다. 이 말은? 함수가 값으로 다뤄질 수 있고, 변수에 담을 수 있다는 것. 아래처럼!

const dapsu = a => a + 30;

console.log(dapsu(5));    // expected output : 35

 

일급함수는 또한 함수의 인자로 사용될 수도 있고, 함수의 결과로  사용될 수도 있다.

const func1 = () => () => 30;
console.log(func1);    // expected output: () => 30

const func2 = func1();
console.log(func2);    // expected output: () => 30
console.log(func2());    // expected output: 30

 

 

함수를 만들어서 리턴하는 함수도 있다. 예를 들어보자.

const addMaker = a => b => a + b;

위의 addMaker라는 함수는 b => a+b 라는 함수를 반환한다. 

 

const add10 = addMaker(10);

console.log(add10(5));    // expected output: 15;

그리고 add10 이라는 함수를 생성하면 addMaker(10)이라는 함수를 리턴하고, add10(5)이면 addMaker(10) 함수에 5의 인자를 추가하여 10+5 로 15라는 결과가 도출된다.

 

이를 클로저를 만들어 리턴하는 함수 라고 표현한다.

 

클로저가 뭔데? addMaker 함수에서 a를 기억하는 것을 클로저라고 강사님이 얘기하셨다. 함수가 함수를 만들어서 리턴하는 것은 결국 클로저가 만들어져서 리턴하는거라고 하심

 

뭔가 애매하다 싶으면 바로 docs 들어가버리기!

 

클로저

클로저는 함수와 함수가 선언된 어휘적(Lexical) 환경의 조합이다.

뭐래.. 일단 예시를 보자구

function makeFunc() {
    const name = "Dapsu";
    function displayName() {
        alert(name);
    }
    return displayName;
}

const myFunc = makeFunc();	//myFunc변수에 displayName을 리턴함

myFunc();	 //리턴된 displayName 함수를 실행(name 변수에 접근)

 

저 코드를 콘솔창에 입력하면 Dapsu라는 알림창이 뜬다. 실행 과정을 살펴 보면, makeFunc() 함수의 리턴값인 displayName() 함수가 myFunc 변수에 저장된다. 그것도 displayName() 함수가 실행되기 전에! 위에서 말했던 일급 함수이기 때문에 가능하겠지?

 

신기한 점은 makeFunc() 실행이 끝나면 함수 내 지역 변수인 name에 접근할 수 없는 것이 일반적인데, 자바스크립트는 경우가 다르다고 한다. 자바스크립트는 함수를 리턴하고, 리턴하는 함수가 클로저를 형성하기 때문이고, 클로저가 생성된 시점의 유효 범위 내에 있는 모든 지역 변수들로 구성되어 있어서... 라고 하는데... 솔직히 뭐라고 하는지 이해 안 간다 ㅠㅠ

 

다시 정리를 해보자. 그니까 변수 name은 displayName() 함수 외부에 있는 변수인데, displayName() 함수가 name에 접근할 수 있다는 것. 이는 displayName()이 makeFunc() 내부에 선언되어 있고, name 역시 makeFunc() 내에 선언되어 있기 때문에 접근이 가능하다는 것이다. 

 

즉 스코프는 함수를 호출할 때가 아니라 함수를 어디에 선언하였는지에 따라 결정되고, 이를 렉시컬 스코핑(Lexical Scoping)이라고 한다. 

 

함수 displayName()은 makeFunc()의 내부함수이므로 이 내부함수는 자신이 속한 렉시컬 스코프(global scope, outer functions scope, local scope)를 참조할 수 있다.

 

 

그럼 다시 본론으로 돌아와서, 클로저는 반환된 내부함수가 자신이 선언됐을 때의 렉시컬 환경인 스코프를 기억하여 자신이 선언됐을 때의 스코프 밖에서 호출되어도 그 환경(스코프)에 접근할 수 있는 함수를 말한다. 그래서 강의에서 강사님이 addMaker 함수의 변수 a를 기억하는 것이라는 말이 이해가 된다!

 

강의 계속 꾸준히 듣자구우우

 

728x90
LIST

댓글