JS/JavaScript&TypeScript

JavaScript&TypeScript 13. 일급 함수

shin96bc 2022. 4. 3. 12:29

(1) 일급 함수( First Class Function )

     Github: https://github.com/SHIN96BC/JavaScript-TypeScript-Concept-2022/tree/main/13_FirstClassFunction

     1) 일급 함수라고 하는 개념은 프로그래밍 언어에서 함수라고 하는 코드의 묶음을 

         일반적인 값처럼 취급하는 개념을 뜻한다.

     2) 함수를 일반 값처럼 취급해서 변수에 넣을 수 있다.

     3) 함수를 변수에 넣을 수 있다는 것은, 함수가 담긴 변수를 또 다른 함수의 인자값으로 줄수도 있고, 
        리턴되는 값이 일반적인 데이터가 아니라 함수가 리턴될 수도 있다는 것이다.
        그래서 좀더 유연한 프로그래밍이 가능해진다.

     4) 인자로 함수가 들어오는 경우( TypeScript )
          ex)
              function ul(child: string): string {
                   return `<ul>${child}</ul>`;
              }

              function makeLI( container: (child: string) => string, contents: string[]): string {
                   const liList = [];

                   for(const content of contents) {
                        liList.push(`<li>${content}</li>`);
                   }

                   return container(liList.join('')); // join 은 배열을 하나의 문자열로 합치는 메소드이다.
              }

              const htmlUL = makeLI(ul, ['월', '회', '수', '목', '금', '토', '일']);

          <1> 함수를 인자로 받아서 리턴시킬때 인자로 받은 함수를 호출해서 나온 리턴값을 다시 

                 리턴하는 구조이다.

          <2> 인자로 넘기 ul 이라고 하는 함수는 인자로 넘기는 단계에서 실행되는게 아니라, 

                 그 함수 자체를 그냥 인자값으로 넘긴것이다.

          <3> 실제로 ul 함수가 호출되는것은 container(liList.join('')); 이부분에서 호출이 된다.
              즉, makeLI 함수가 ul 함수를 호출하게 되는 것이다.

          <4> 여기서 makeLI 의 container 라는 함수를 담은 변수는 인자값으로 들어온 함수가 어떤것인지 

                 전혀 몰라도 된다. 형식만 맞다면 다른 어떤 함수를 넣어서도 사용할 수 있다. 

                 즉, makeLI '함수의 코드를 바꾸지 않고도' 인자값으로 주는 함수를 갈아끼워서 

                 '다른 일을 하게 할 수 있다'.

          <5> makeLI 함수가 하는일을 makeLI 가 직접 정하는 것이 아니라, 바깥쪽애서 결정하게 해서 

                 좀더 유연하게 사용할 수 있게 된다.

          <6> 그래서 일급 함수에는 여러가지 일을 하는 코드가 있으면 안된다. 딱 한가지 일에만 

                 집중할 수 있게 설계해야한다. 그리고 나머지 일들에 필요한 코드는 인자로 넘겨받은 

                 함수에 들어있어야 하고, 일급 함수는 그 인자로 받은 함수들을 사용해서

                 일을 처리해야 한다.

     5) 반환 값으로 함수가 반환되는 경우( JavaScript )
          ex)
              function discountPrice(discountRate) {
                   return function(price) {
                        return price - (price * (discountRate * 0.01));
                   }
              }
              console.log('여름 세일 - ' + discountRate(30)(567000));
              console.log('겨울 세일 - ' + discountRate(10)(567000));

          <1> 호출할때 처음 () 는 바깥쪽 함수 discountPrice 에 인자값을 넘기고, 두번째 ()는 return 에 있는 

                 함수에 인자값을 넘긴다. 그래서 총 두번 호출해줘야 하는 것이다.

          <2> 이것을 변수를 이용해서 좀더 응용할 수 있다.( 이 방법을 사용하자. )
               ex) 
                   let summerPrice = discountPrice(30);
                   let winterPrice = discountPrice(10);

                   console.log('여름 세일 - ' + summerPrice(567000));
                   console.log('겨울 세일 - ' + winterPrice(567000));

               1> 이렇게 사용하게되면, discountPrice(30) 을 수행해서 반환된 함수가 변수 summerPrice 에 

                    넣어서 사용할 수 있다.
               2> 그래서 그 다음번에 호출할때는 함수가 들어있는 변수를 함수처럼 사용할 수 있다.
               3> summerPrice(567000)); 이런식으로 안쪽에 있던 함수를 호출 할 수 있게 되는 것이다.
               4> 변수에 넣어서 사용하는 방식의 장점은 호출하는 코드만 보고 변수명으로 어떤일을 하는 

                    함수인지 바로 알 수 있다는 것이다.