2 분 소요

함수 : First-clas citizen(일급객체)


자바스크립트에서 일급객체인 함수는

  1. 변수에 할당할 수 있고,
  2. 다른 함수의 인자로 전달될 수 있고,
  3. 다른 하수의 결과로서 리턴될 수 있다.

라는 특징을 가지고 있다. 이러한 특징을 통해 고차 함수로 적용될 수 있다.

고차함수

고차함수는 함수를 인자로 받을 수 있고, 함수의 형태로 리턴하는 형태로 동작하는 함수를 말한다.

  • 다른 함수의 인자로 전달되는 함수 : 콜백함수
    • 이때 콜백함수를 전달받은 고차함수는 함수 내부에서 이 콜백 함수를 호출 및 실행이 가능하다.
function double(num) {
  return num*2;
}

//고차 함수
// 여기서 인자 func은 doubleAdder의 콜백 함수로 함수 double은 함수 doubleAdder의 콜백으로 전달된다.
function doubleAdder(added, func) {
  const doubled = func(added);
  return function(num) {
    return num + doubled;
  };
}

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

//doubleAdder가 리턴하는 함수를 변수에 저장할 수 있다.
const addTwice3 = doubleAdder(3,double);
addTwice3(2); // ->8
  • 고차함수는 또한, 인자로 함수를 여러개 받을 수 있으며, Rest Parameters를 통해서 접근이 가능하다.
//Rest Parameters(...)을 통해 각 함수에 접근한다.
function pipe(...funcs) {
  return function (num) {
    let result = num;
    for (let i = 0; i < funcs.length; i++) {
      result = funcs[i](result);
    }
    return result;
  };
}


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

function add5(num) {
  return num + 5;
}

function mul3(num) {
  return num * 3;
}

function isOdd(num) {
  return num % 2 !== 0;
}

let output = pipe(add5, square);
console.log(output(4)); // --> 81

output = pipe(square, add5, mul3);
console.log(output(4)); // --> 63

output = pipe(square, mul3, add5, add5, isOdd);
console.log(output(4)); // --> false

내장 고차함수 : Map, Filter, Reduce


Map : 배열의 각 요소가 특정 함수에 의해 다른 요소로 지정되는 함수

  • 기존 배열을 수정하지 않는다.
  • ex.
let arr = [1,2,3];

let result = arr.map(function(element) {
	return ele*2;
});

console.log(result) // -> 2,4,6

Filter: 배열의 각 요소가 함수에 따르면 사실(True)일때 따로 분류하는 함수

  • 기존 배열을 수정하지 않는다.
  • ex.
let arr = [1,2,3];

let result = arr.filter(function(element) {
  return element%2 !== 0
});

console.log(result) // -> 1,3

Reduce : 배열의 각 요소를 특정 함수에 따라 원하는 하나의 형태로 응축한다.

  • 누적값, 현재값, 인덱스 등을 인자로 갖을 수 있고
  • 누적값의 값을 반환한다.
  • ex.
let arr = [1,2,3]

let result = arr.reduce(function(acc,cur,idx) {
	return acc+cur;
},0) // 0은 초기값
  • 연산뿐만 아니라 배열을 문자열로, 배열을 객체로 데이터 처리에서도 사용될 수 있다.
  • Ex. 배열을 객체로
function makeAddressBook(addressBook, user) {
	let firstLetter =user.name[0];
  
  if(firstLetter in addressBook) {
		addressBook[firstLetter].push(user);
  } else {
    addressBook[firstLetter] = [];
    addressBook[firstLetter].push(user);
  }
  
  return addressBook;
}

let users = [
  {name: 'Tim', age: 40},
  {name: 'Satya', age:30},
  {name: 'Sundar', age:50}
];

users.reduce(makeAddressBook, {});

왜 고차함수를 써야할까


“추상화 : 복잡한 어떤 것을 압축해서 핵심만 추출한 상태”

추상화는 어디에나 적용되고, 그냥 함수도 추상화의 개념을 도입하여 생산성을 향상한 좋은 사례이다. 따라서 고차함수 또한, 높은 수준의 추상화의 이점을 가지며 생산성이 비약적으로 상승하기 때문에 사용한다.

  • 함수의 추상화 수준 : 값 수준에서의 추상화
    • 함수 = 값을 전달받아 값을 리턴 = 값에 대한 복잡한 로직은 감추어져 있음 = 값 수준에서의 추상화
  • 고차함수의 추상화 수준 : 사고 수준에서의 추상화
    • 고차함수 = 함수를 전달받거나 함수를 리턴 = 사고에 대한 복잡한 로직은 감추어져 있음. = 사고 수준에서의 추상화

본 포스팅은 코드스테이츠 BEB 과정을 수강하며 작성한 글입니다.