[JavaScript] 고차함수

Jun·2022년 6월 5일

JavaScript

목록 보기
9/13
post-thumbnail

일급 객체 (first-class object)

다들 버스나 기차, 혹은 비행기 좌석 중 일등석(first-class)에 대해 알고 있을것이다.
가장 좋은 좌석을 뜻하며 그에 따른 편리함과 추가적인 서비스가 제공된다.

JavaScript에도 특별한 대우를 받는 일급 객체(first-class object)가 존재한다.
대표적인 일급객체중 하나가 바로 함수이다. JavaScript에서 함수가 받는 특별한 대우란 무엇일까?

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

함수를 변수에 할당할 수 있기 때문에, 함수를 배열의 요소나 객체의 속성값으로 지정할 수 있다.
즉, 함수를 데이터(string, number, boolean, array, object)같이 다룰 수 있다.

고차 함수 (higher order function)

고차 함수는 함수를 전달인자로 받을 수 있고, 반환할 수 있는 함수이다.

이 때, 다른 함수(caller)의 전달인자(argument)로 전달되는 함수를 콜백 함수(callback function)라고 한다. 어떠한 작업이 완료되었을 때 호출되는 경우가 많아, 답신 전화를 뜻하는 콜백이 수식어로 붙여졌다.

콜백 함수를 전달받은 고차 함수는, 함수 내부에서 콜백 함수를 호출(invoke)할 수 있고, 조건에 따라 콜백 함수의 실행 여부를 결정할 수도 있다.

'함수를 반환하는 함수'는 모양새가 특이한 만큼, 부르는 용어가 따로 있다. 이것을 고안해 낸 논리학자 하스켈 커리(Haskell Curry)의 이름을 따, 커링 함수라고 한다.

클로저와 커링함수

커링함수를 보면 클로저와 비슷하다는 생각이 들 것이다.
정답이다. 조금 더 자세하게 말하자면 커링함수는 클로저를 이용한 함수이다.
다음 코드를 보자.

function add3(a,b,c) {
  return a+b+c;
}

console.log(add3(3,4,5)); // output : 3+4+5 = 12
console.log(add3(3,5,6)); // output : 4+5+6 = 15
console.log(add3(3,7,10)); // output : 3+7+10 = 20

3을 더해주는 함수 add3 의 첫번째 인자는 모두 3이라는 공통점이 있지만, 함수를 사용할때마다 3을 인자로 지정해줘야한다.

이 때 커링함수를 사용한다면 특정 인자를 재사용할 수 있다.

// 클로저를 이용한 커링함수

function addMaker(a) {
  return function (b) {
    return function(c) {
		return a+b+c
    }
  }
}

const add3 = addMaker(3); // 첫 번째 인자를 3으로 고정
console.log(add3(4)(5)); // output : 3+4+5 = 12

클로저를 이용하여 외부 함수 변수의 값을 고정시킨 뒤 나머지 인자를 받고있다.
이렇듯이 커링함수는 클로저의 외부 함수 변수의 값을 고정하여 사용 가능하다.

내장 고차 함수

filter

filter() 메서드는 주어진 함수의 테스트를 통과하는 모든 요소를 모아 새로운 배열로 반환한다.

인자로 콜백 함수를 받으며 이 콜백 함수는 각 요소를 시험할 함수이다. true 를 반환하면 요소를 유지하고, false 를 반환하면 버린다.

이 콜백 함수는 인자 세 개(element[, index[, array]])를 가진다.

arr.filter(callback(currentValue[, index[, array]]),[, thisArg])

  • element : 처리할 현재 요소
  • index (Optional) : 처리할 현재 요소의 index
  • array (Optional) : filter를 호출한 배열
  • thisArg (Optional) : 콜백함수를 실행할 때 this 로 사용되는 값
const nums = [1,2,3,4,5,6,7,8,9,10];
const evenNums = nums.filter(num => num%2 === 0);
// 배열의 요소를 순회하여 요소가 짝수라면 true 반환하므로 새 배열에 저장

console.log(evenNums) // output : [2,4,6,8,10]

map

map() 메서드는 배열 내의 모든 요소 각각에 대하여 주어진 함수를 호출한 결과를 모아 새로운 배열로 반환한다.

인자로 콜백 함수를 받으며, 이 콜백 함수는 새로운 배열 요소를 생성하는 함수이다.

이 콜백 함수는 인자 세 개(currentValue[, index[, array]])를 가진다.

arr.map(callback(currentValue[, index[, array]])[, thisArg])

  • currentValue : 처리할 현재 요소
  • index (Optional) : 처리할 현재 요소의 index
  • array (Optional) : map() 을 호출한 배열
  • thisArg (Optional) : 콜백함수를 실행할 때 this 로 사용되는 값
const nums = [1,2,3,4,5];
const multiply2 = nums.map(num => num*2); 
// 배열의 각 요소마다 2를 곱하여 새 배열에 저장

console.log(multiply2) // output : [2,4,6,8,10]

reduce

reduce() 메서드는 배열의 각 요소에 대해 주어진 리듀서(reducer) 함수를 실행하고, 하나의 결과값을 반환한다.

reduce() 는 인자로 reducer 콜백함수와 initialValue를 가지고
reducer 콜백함수는 인자로 acc, cur, idx, arr을 가진다.

arr.reduce(callback[, initialValue])

  • accumulator : 콜백함수의 반환값을 누적한다. 콜백의 이전 반환값 또는, 콜백의 첫 번째 호출임과 동시에 initialValue 를 전달받은 경우엔 initialValue 의 값이다.
  • currentValue : 처리할 현재 요소
  • currentIndex (Optional) : 처리할 현재 요소의 인덱스. initialValue 를 제공한 경우 0, 아니면 1부터 시작한다.
  • array (Optional) : reduce()를 호출한 배열.

  • initialValue (Optional) : 콜백함수의 최초 호출에서 첫 번째 인수에 제공하는 값. 초기값을 제공하지 않으면 배열의 첫 번째 요소를 사용한다.
const nums = [2,3,4,5]

// initialValue가 없을 경우
let result = nums.reduce((acc,cur) => acc+cur)
console.log(result) // output : 2+3+4+5 = 14

// initialValue로 1을 전달해 주는 경우
result = nums.reduce((acc,cur) => acc+cur, 1)
console.log(result) // output : 1+2+3+4+5 = 15
profile
FrontEnd Engineer를 목표로 공부합니다.

0개의 댓글