고차함수

katsukichi·2021년 2월 1일
0

CodeStates_PRE

목록 보기
20/27

1. 일급객체(first-class citizen)의 세가지 특징

특별한 대우를 받는 함수?

퍼스트클래스? 뭐지 비행기에 퍼스트클래스가 먼저 떠오른다.

비싸고,편하고, 일부만해당하고?
특별한 대우를받는다 ?

js세계에서도 특별한 대우를 받는것들이 있다.

이런것들은 일급객체 (first-class citizen)이라고 한다.

그 중 하나가 함수(function)이다.

즉 자바스크립트에서 함수는(자바스크립트가 나온 시점을 고려했을때) 아래와 같이 특별하게 취급된다.

  • 변수에 할당(assignment)할 수있다.
  • 다른 함수의 인자(argument)로 전달될 수 있다.
  • 다른 함수의 결과로서 리턴될 수있다.

이는 함수를 데이터(string number boolean array object)를 다루듯이 다룰 수 있다는걸 의미,
변수에 저장할 수 있기 때문에 배열의 요소나 객체의 속성값으로 저장하는 것도 가능

그게바로 함수표현식(function expression)이다.

아래 함수 표현식은 함수선언식(function declaration)과 다르게 호이스팅(hoisting)이 적용되지 않는다.

  1. 변수에 함수를 할당하는 경우

const square = function(num) {
  return num * num;
};

output = square(7);
console.log(output);

함수선언식의 호이스팅에 지나치게 의존하는것은 코드의 유지/보수 측면에서 좋지않다.

코드리뷰나 디버깅할때 코드를 위 아래오 왔다갔다 하게될수 있다.

반면 함수 표현식은 함수의 할당과 실행의 위치가 중요하기때문에 코드의 위치가 어느정도 예측가능하다.

호이스팅을빼면 함수선언식,표현식이 크게 차이가없다.

실제로도그렇지만 다만, 함수 표현식은 함수가 변수에 저장될 수있다는 사실을 좀 더 분명하게 드러낼 수 있다.

변수에 저장된 데이터는 함수의 인자로 전달되거나 함수 내에서 리턴값으로 사용될 수있다. 앞서 함수가 변수에 저장될 수 있다는 사실로부터, 함수 역시 다른 함수의 인자로 전달되거나 다른 함수내에서 리턴될 수 있다는것을 알 수 있습니다. 자바스크립트의 고급 주제인 고차함수(higher order function)은 여기서부터 시작된다.

2. 고차함수(higher-order function)에 대한 설명

고차함수? 함수를인자(argument)로 받거나 함수를 리턴하는 함수를 말한다.

이 때 다른 함수(caller)의 인자(argument)로 전달되는 함수를 콜백 함수(callback function)라고 한다.
콜백함수는 앞으로 엄청쓸꺼니까 정의에대해서 충분히 숙지하는게 좋다.

콜백함수를 전달받은 함수는 콜백함수를 호출(invoke)할 수있다. 조건에 따라 콜뱀함수의 실행여부를 결정할수있고, 여러번 실행할수도있다.콜백은 어떤작업이 완료되었을때 호출되는 경우가 많아서 답신전화를 뜻하는 콜백이라는 이름이 붙여졌다.

한편 함수를 리턴하는 함수만을 일컫는 용어가 따로 존재하고 실제로 많이 쓴다.
논리학자 하스켈 커리(Haskell Curry)의 이름을 따라 커리함수라고 한다.
(콜백함수개념만 고차함수에 포함시키고 커리함수는 따로 구분하는경우도 있지만, 엄밀한 의미에서 고차함수는 커리함수를 포함한다.)

3. 고차함수를 js로 작성예시

1. 다른 함수를 인자로 받는 경우


function double(num) {
  return num * 2;
}

function doubleNum(func, num) {
  return func(num);
}

// 함수 doubleNum은 다른 함수를 인자로 받는 고차 함수입니다.
// 함수 doubleNum의 첫 번째 인자 func에 함수가 들어올 경우
// 함수 func는 함수 doubleNum의 콜백 함수입니다.
// 아래와 같은 경우, 함수 double은 함수 doubleNum의 콜백 함수입니다.
let output = doubleNum(double, 4);
console.log(output); // -> 8

2. 함수를 리턴하는 경우


function adder(added) {
  return function (num) {
    return num + added;
  };
}

// 함수 adder는 다른 함수를 리턴하는 고차 함수입니다.
// adder는 인자 한 개를 입력받아서 함수(익명 함수)를 리턴합니다.
// 리턴되는 익명 함수는 인자 한 개를 받아서 added와 더한 값을 리턴합니다.

// adder(5)는 함수이므로 함수 호출 연산자 '()'를 사용할 수 있습니다.
let output = adder(5)(3); // -> 8
console.log(output); // -> 8

// adder가 리턴하는 함수를 변수에 저장할 수 있습니다.
// javascript에서 함수는 일급 객체이기 때문입니다.
const add3 = adder(3);
output = add3(2);
console.log(output); // -> 5

3. 함수를 인자로 받고, 함수를 리턴하는 경우


function double(num) {
  return num * 2;
}

function doubleAdder(added, func) {
  const doubled = func(added);
  return function (num) {
    return num + doubled;
  };
}

// 함수 doubleAdder는 고차 함수입니다.
// 함수 doubleAdder의 인자 func는 함수 doubleAdder의 콜백 함수 입니다.
// 함수 double은 함수 doubleAdder의 콜백으로 전달되었습니다.

// doubleAdder(5, double)는 함수이므로 함수 호출 기호 '()'를 사용할 수 있습니다.
doubleAdder(5, double)(3); // -> 13

// doubleAdder가 리턴하는 함수를 변수에 저장할 수 있습니다. (일급 객체)
const addTwice3 = doubleAdder(3, double);
addTwice3(2); // --> 8

더알면 좋은내용

  • MapReduce 학습하기 (MapReduce Model)
  • 자바스크립트에서 커링(currying)과 클로져(closure)의 차이 이해하기 (js closure vs curry)
  • 선언형 프로그래밍(declarative programming)과 절차형 프로그래밍(imperative programming)의 차이를 배열 메소드를 통해 이해하기 (js imperative vs declarative)
  • 함수의 조합(function composition)에 대해 학습하기 (javascript function composition)
profile
front-back / end developer / Let's be an adaptable person

0개의 댓글