12. [JavaScript] 고차함수

문도연·2022년 6월 9일
0

Chapter1. 고차 함수
1-1. 일급 객체
1-2. 고차 함수의 이해

Chapter2. 내장 고차 함수
2-1. 내장 고차 함수의 이해
2-2. 내장 고차 함수 filter
2-3. 내장 고차 함수 map
2-2. 내장 고차 함수 reduce

Chapter3. 고차 함수의 중요성
3-1. 고차 함수를 쓰는 이유
3-2. 고차함수와 추상화


Chapter1. 고차 함수

  • 일급 객체(first-class citizen)의 세 가지 특징을 설명할 수 있다.
  • 고차 함수(higher-order function)에 대해 설명할 수 있다.
  • 고차 함수를 자바스크립트로 작성할 수 있다.

1-1. 일급 객체

JavaScript에도 특별한 대우를 받는 일급 객체(first-class citizen)가 있음
대표적인 일급 객체 중 하나가 함수

JavaScript에서 함수는 아래와 같이 특별하게 취급됨

  • 변수에 할당(assignment) 할 수 있다.

  • 다른 함수의 전달인자(argument)로 전달될 수 있다.

  • 다른 함수의 결과로서 리턴될 수 있다.

    • 함수를 변수에 할당할 수 있기 때문에, 함수를 배열의 요소나 객체의 속성값으로 저장할 수 있습니다.
    • 함수를 데이터(string, number, boolean, array, object)처럼 다룰 수 있습니다.
//변수에 함수를 할당하는 경우 (함수표현식)
const square = function (num) {
    return num*num;
};

함수 표현식은 변수에 할당한 다음 사용할 수 있음
함수는 변수에 저장된 데이터를 전달 인자로 받거나, 리턴 값으로 사용할 수 있습니다.
함수도 변수에 저장될 수 있기 때문에 함수를 인자로 받거나, 리턴 값으로 사용할 수 있습니다.

함수는 일급 객체의 특징을 가지기 때문에 아래처럼 객체 속성의 값으로 할당될 수 있다.

const cat = {
	name: 'nabi',
	age: 3,
	cry: function(){
	 console.log('miaow...') 
	}
}

1-2. 고차 함수의 이해

고차 함수(higher order function)는 함수를 전달인자(argument)로 받을 수 있고, 함수를 리턴할 수 있는 함수입니다.

전달인자(argument)로 전달되는 함수를 콜백 함수(callback function)라고 합니다.

콜백 함수를 전달받은 고차 함수(caller)는, 함수 내부에서 이 콜백 함수를 호출(invoke)할 수 있고,

조건에 따라 콜백 함수의 실행 여부를 결정할 수도 있습니다.


Chapter2. 내장 고차 함수

  • 배열 내장 고차 함수 filter에 대해서 이해할 수 있다.
  • filter에 대한 이해를 기반으로, 나머지 내장 고차 함수를 학습할 수 있다.
    • filter, map, reduce, forEach, find, sort, some, every
  • 고차 함수를 쓰는 이유를 설명할 수 있다.
  • 고차 함수를 활용하여 프로그램을 작성할 수 있다.

2-1. 내장 고차 함수의 이해

JavaScript에는 기본적으로 내장된 고차 함수가 여럿 있습니다.
그중에서 배열 메서드들 중 일부가 대표적인 고차 함수에 해당합니다.
내장 고차 함수를 이해하고 map, filter, reduce를 상세히 학습합니다.

2-2. 내장 고차 함수 filter

filter

조건에 맞는 데이터만 분류(filtering) 할 때 사용한다

  • 배열의 filter 메서드는, 모든 배열의 요소 중에서 특정 조건을 만족하는 요소를 걸러내는 메서드입니다.
    • 여기서 걸러내는 기준이 되는 특정 조건은 filter 메서드의 전달인자로 전달됩니다.
    • 이때 전달되는 조건은 함수의 형태입니다.
    • filter 메서드는 배열의 요소를 콜백 함수에 다시 전달합니다
      • 콜백 함수는 전달받은 배열의 요소를 받아 함수를 실행하고, 콜백 함수 내부의 조건에 따라 참(true) 또는 거짓(false)을 리턴합니다.
  • filter 메서드는, 걸러내기 위한 조건을 명시한 함수를 전달인자로 받기 때문에 고차 함수입니다.

filter 활용 시, 아래 과정을 꼭 기억하세요.

  • 배열의 각 요소가
  • 특정 논리(함수)에 따르면, 사실(true)일 때
  • 따로 분류합니다(filter)

예제

const isLteFive = function (str) {
  // Lte = less then equal
  return str.length <= 5;
};

arr = ['hello', 'code', 'states', 'happy', 'hacking'];

let output = arr.filter(isLteFive);
console.log(output); // ->> ['hello', 'code', 'happy']

2-3. 내장 고차 함수 map

map

하나의 데이터를 다른 데이터로 매핑(mapping) 할 때 사용
모든 요소에게 동일한 행동을 주고 그 값에을 모두 리턴함

map 활용 시, 아래 과정을 꼭 기억하세요.

  • 배열의 각 요소가
  • 특정 논리(함수)에 의해
  • 다른 요소로 지정(map) 됩니다.

예제

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

let arr = [1, 2, 3, 4, 5, 6, 7];
let output = arr.map(double);
console.log(output); // [2, 4, 6, 8, 10, 12, 14]

2-4. 내장 고차 함수 reduce

reduce

여러 데이터를, 하나의 데이터로 응축(reduce)할 때 사용

  • 배열을 하나의 값으로 리턴한다.
    • 초기값을 정할 수 있는데, 초기값을 정하지 않는다면 첫번째 인덱스값이 설정됨 - 이 초기값은 누적값의 기반이 된다

reduce 활용 시, 아래 과정을 꼭 기억하세요.

  • 배열의 각 요소를
  • 특정 방법(함수)에 따라
  • 원하는 하나의 형태로 응축합니다. (reduction)

예제(초기값설정x)

const addAccCur = function (acc, cur) {
  return acc + cur;
};

let arr = [1, 2, 3, 4, 5, 6, 7];
let output = arr.reduce(addAccCur);
console.log(output); // ->> 28

초기값이 없으므로 acc = 1 (arr의 0번째 인덱스값) 부터 시작
acc + cur = acc
1 + 2 = 3
3 + 3 = 6
6 + 4 = 10
10 + 5 = 15
15 + 6 = 21
21 + 7 = 28

예제(초기값설정o)

const addAccCur = function (acc, cur) {
  return acc + cur;
};
const initialValue = 1;

let arr = [1, 2, 3, 4, 5, 6, 7];
let output = arr.reduce(addAccCur, initialValue);
console.log(output); // ->> 29

초기값이 1 이므로 acc(누적값) = 1 (initialValue)부터 연산 시작
acc + cur = acc
1 + 1 = 2
2 + 2 = 4
4 + 3 = 7
7 + 4 = 11
11 + 5 = 16
16 + 6 = 22
22 + 7 = 29

reduce 활용

  • 숫자 더하기 빼기
  • 배열을 문자열로
  • 문자열합치기
  • 숫자 크기 비교가능
  • 배열을 객체로

Chapter3 고차 함수의 중요성

  • 추상화에 대해 설명할 수 있다.
  • 추상화의 관점에서 고차 함수가 갖는 이점에 대해 설명할 수 있다.
  • 고차 함수를 통해 사고 수준에서의 추상화를 달성할 수 있다.

3-1. 고차 함수를 쓰는 이유

추상화

복잡한 어떤 것을 압축해서 핵심만 추출한 상태로 만드는 것을 뜻함

추상화 사례

스마트폰으로 카카오톡이나 페이스북 메신저를 통해 친구에게 '안녕' 이란 메시지를 보내면, 그 순간 여러분들의 스마트폰은 기지국과 약 20개의 메시지를 주고받습니다.
걍 우리는 입력창에 메시지를 입력하고 전송 버튼을 누르면, 내 친구가 메시지를 받는다는 사실만 알고 있지, 스마트폰이 그 20개의 메시지를 기지국과 어떻게 주고 받는지 모르고, 알 필요도 없음

자바스크립트를 비롯한 많은 프로그래밍 언어 역시, 추상화의 결과입니다.
컴퓨터를 구성하는 장치(중앙처리장치, CPU; Central Processing Unit)는 0과 1만 이해합니다.
크롬 개발자 도구의 콘솔(console) 탭에서 다음의 코드를 입력했을 때,
어떤 과정을 거쳐 10이 출력되는지 몰라도 10을 출력할 수 있습니다.
그런 복잡한 것들은 크롬의 자바스크립트 해석기(엔진)가 대신해 주기 때문

추상화의 이점

생산성(productivity)의 향상

함수와 추상화 : 값 수준 vs 사고 수준

프로그램을 작성할 때, 자주 반복해서 사용하는 로직은 별도의 함수로 작성하기도 합니다.
이 역시 추상화의 사례임

값 수준의 추상화 사례

함수 = 을 전달받아 값을 리턴한다 = 값에 대한 복잡한 로직은 감추어져 있다 = 값 수준에서의 추상화

function sum(num1, num2) {
  return num1 + num2;
}
const output = sum(3, 7);
console.log(output); // --> 10

사고 수준에서의 추상화

고차 함수는 추상화의 수준을 사고의 추상화 수준으로 끌어올립니다. 추상화는 고차 함수를 통해, 보다 쉽게 달성할 수 있음!

  • 값 수준의 추상화: 단순히 값(value)을 전달받아 처리하는 수준
  • 사고의 추상화: 함수(사고의 묶음)를 전달받아 처리하는 수준

고차 함수 = 함수를 전달받거나 함수를 리턴한다 = 사고(함수)에 대한 복잡한 로직은 감추어져 있다 = 사고 수준에서의 추상화
-> 생산성도 비약적으로 상승

3-2. 고차함수와 추상화

사고 수준에서의 추상화 사례

//함수를 전달받는 경우
const menus  = ['americano', 'herb tea', 'earlgrey tea', 'hot choco']
const isTea = function (menu) {
  if (menu.includes('tea')) {
    return true
  }
}
let output = menus.filter(isTea);
console.log(output); //['herb tea', 'earlgrey tea']

추가학습

  • MapReduce 학습하기 (MapReduce Model)
  • 자바스크립트에서 커링(currying)과 클로저(closure)의 차이 이해하기 (js closure vs curry)
  • 선언형 프로그래밍(declarative programming)과 절차형 프로그래밍(imperative programming)의 차이를 배열 메서드를 통해 이해하기 (js imperative vs declarative)
  • 함수의 조합(function composition)에 대해 학습하기 (javascript function composition)
profile
중요한건 꺾이지 않는 마음이 맞는 것 같습니다

0개의 댓글