| 일 | 월 | 화 | 수 | 목 | 금 | 토 |
|---|---|---|---|---|---|---|
| 1 | 2 | 3 | 4 | 5 | 6 | |
| 7 | 8 | 9 | 10 | 11 | 12 | 13 |
| 14 | 15 | 16 | 17 | 18 | 19 | 20 |
| 21 | 22 | 23 | 24 | 25 | 26 | 27 |
| 28 | 29 | 30 |
- Spring
- 디자인챌린지
- 오픈패스
- 티스토리챌린지
- UXUI챌린지
- 디자인교육
- Java
- 백준
- 시스템설계
- Be
- UXUIPrimary
- 부트캠프
- 백엔드개발자
- 오블완
- baekjoon
- OPENPATH
- 국비지원교육
- 오픈챌린지
- 국비지원취업
- API
- 디자인강의
- KDT
- UXUI기초정복
- JPA
- 패스트캠퍼스
- 환급챌린지
- 국비지원
- mysql
- 백엔드 부트캠프
- 내일배움카드
- Today
- Total
군만두의 IT 개발 일지
[DAY6] JavaScript 고차 함수 본문
목차
🚀 진행기간: 2023년 6월 26일 ~ 2023년 7월 13일
⭐요약
JavaScript에서 고차 함수(Higher Order Function)와 내장 고차 함수, 그리고 추상화 관점에서의 고차 함수의 중요성에 대해 정리한다.
| Chapter 1. 고차 함수 | 함수는 일급 객체이므로 변수에 할당하거나 다른 함수의 인자·리턴값으로 사용할 수 있음. 고차 함수는 함수를 인자로 받거나 함수를 리턴하는 함수이며, 인자로 전달되는 함수를 콜백 함수라 함. |
| Chapter 2. 내장 고차 함수 | filter: 조건을 만족하는 요소만 걸러내 새 배열로 반환함. map: 모든 요소에 동일한 동작을 적용시켜 새 배열로 반환함. reduce: 배열의 여러 요소를 하나의 값으로 응축함. |
| Chapter 3. 고차 함수의 중요성 | 고차 함수는 사고(함수) 수준에서의 추상화를 달성하여 코드의 재사용성과 생산성을 높임. 각각의 함수를 compose로 조합하면 복잡한 로직도 선언적으로 표현할 수 있음. |
⭐고차 함수(Higher Order Function)
1. 일급 객체
JavaScript에서 함수는 대표적인 일급 객체(First-Class Object)이다. 일급 객체란 아래 세 가지 특징을 모두 만족하는 객체를 말한다.
- 변수에 할당(assignment)할 수 있다.
- 다른 함수의 전달인자(argument)로 전달될 수 있다.
- 다른 함수의 결과값으로 리턴될 수 있다.
2. 고차 함수의 이해
- 고차 함수(Higher Order Function): 함수를 전달인자(argument)로 받을 수 있고, 함수를 리턴할 수 있는 함수이다.
- 다른 함수(caller)의 전달인자로 전달되는 함수를 콜백 함수(callback function)라고 한다.
🚀 고차 함수의 세 가지 형태
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
⭐내장 고차 함수
1. filter
- filter: 배열의 모든 요소 중에서 특정 조건을 만족하는 요소만 걸러내 새 배열로 반환한다.
- 특정 조건은
filter메서드의 전달인자로 함수 형태로 전달된다. 따라서filter는 고차 함수이다. - 원본 배열은 변경되지 않는다.
// 함수 표현식
const isEven = function (num) {
return num % 2 === 0;
};
let arr = [1, 2, 3, 4];
// '짝수'를 판별하는 함수가 조건으로서 filter 메서드의 전달인자로 전달됩니다.
let output = arr.filter(isEven);
console.log(output); // ->> [2, 4]
const isLteFive = function (str) {
// Lte = less than equal
return str.length <= 5;
};
arr = ['hello', 'code', 'states', 'happy', 'hacking'];
// '길이 5 이하'를 판별하는 함수가 조건으로서 filter 메서드의 전달인자로 전달됩니다.
let output2 = arr.filter(isLteFive);
console.log(output2); // ->> ['hello', 'code', 'happy']
2. map
- map: 하나의 데이터를 다른 데이터로 매핑(mapping)할 때 사용한다.
- 모든 요소에 동일한 동작을 적용시킨 뒤 새 배열로 반환한다.
- 원본 배열은 변경되지 않는다.
const cartoons = [
{
id: 1,
bookType: 'cartoon',
title: '식객',
subtitle: '어머니의 쌀',
createdAt: '2003-09-09',
genre: '요리',
artist: '허영만',
averageScore: 9.66,
},
{
id: 2,
// .. 이하 생략
},
// ... 이하 생략
];
// 만화책 한 권의 부제를 리턴하는 로직(함수)
const findSubtitle = function (cartoon) {
return cartoon.subtitle;
};
// 각 책의 부제 모음
const subtitles = cartoons.map(findSubtitle); // ['어머니의 쌀', ...]
3. reduce
- reduce: 여러 데이터를 하나의 데이터로 응축(reduce)할 때 사용한다.
function joinName(resultStr, user) {
resultStr = resultStr + user.name + ', ';
return resultStr;
}
let users = [
{ name: 'Tim', age: 40 },
{ name: 'Satya', age: 30 },
{ name: 'Sundar', age: 50 }
];
users.reduce(joinName, '');
⭐고차 함수의 중요성
1. 고차 함수를 쓰는 이유 — 추상화
- 추상화(Abstraction): 복잡한 어떤 것을 압축해서 핵심만 추출한 상태로 만드는 것을 말한다.
- 추상화는 생산성(productivity)의 향상으로 이어진다.
🚀 함수와 고차 함수의 추상화 수준 비교
| 구분 | 설명 | 추상화 수준 |
| 함수 | 값을 전달받아 값을 리턴함. 값에 대한 복잡한 로직은 감추어져 있음 | 값(value) 수준의 추상화 |
| 고차 함수 | 함수를 전달받거나 함수를 리턴함. 사고(함수)에 대한 복잡한 로직은 감추어져 있음 | 사고(thought) 수준의 추상화 |
고차 함수는 추상화의 수준을 값 수준에서 사고의 수준으로 끌어올린다.
2. 고차 함수와 추상화
아래 코드는 여러 함수를 순서대로 조합하는 고차 함수 compose의 예시이다. 각각의 함수는 단일 목적을 가지며, 다른 목적을 위해 재사용(reuse)될 수 있다.
function getOnlyMales(data) {
return data.filter(function (d) {
return d.gender === 'male';
});
}
function getOnlyAges(data) {
return data.map(function (d) {
return d.age;
});
}
function getAverage(data) {
const sum = data.reduce(function (acc, cur) {
return acc + cur;
}, 0);
return sum / data.length;
}
function compose(...funcArgs) {
// compose는 여러 개의 함수를 인자로 전달받아 함수를 리턴하는 고차 함수입니다.
// compose가 리턴하는 함수(익명 함수)는 임의의 타입의 data를 입력받아,
return function (data) {
// funcArgs의 요소인 함수들을 차례대로 적용(apply)시킨 결과를 리턴합니다.
let result = data;
for (let i = 0; i < funcArgs.length; i++) {
result = funcArgs[i](result);
}
return result;
};
}
// compose를 통해 함수들이 순서대로 적용된다는 것이 직관적으로 드러납니다.
// 각각의 함수는 다른 목적을 위해 재사용(reuse) 될 수 있습니다.
const getAverageAgeOfMale = compose(
getOnlyMales, // 배열을 입력받아 배열을 리턴하는 함수
getOnlyAges, // 배열을 입력받아 배열을 리턴하는 함수
getAverage // 배열을 입력받아 `number` 타입을 리턴하는 함수
);
const result = getAverageAgeOfMale(data);
console.log(result); // --> 26
⭐후기
- 일급 객체와 고차 함수의 개념을 처음 접했을 때는 낯설었지만, 콜백 함수 예를 통해 이미 사용해 왔다는 것을 깨달았다.
filter,map,reduce는 앞으로 데이터를 다룰 때 많이 사용하게 될 메서드인 만큼, 세 가지의 차이점과 활용법을 확실히 익혀야겠다.
⭐참고자료
1) MDN Web Docs, "Array.prototype.filter()", https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Array/filter
2) MDN Web Docs, "Array.prototype.map()", https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Array/map
3) MDN Web Docs, "Array.prototype.reduce()", https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Array/reduce
이 글은 코드스테이츠 x KNU가 주최한 직무역량캠프에서 공부한 내용을 작성한 것입니다.
'개발일지 > SW직무역량 부트캠프' 카테고리의 다른 글
| [DAY7] JS/Node 비동기 (0) | 2023.07.07 |
|---|---|
| [DAY6] JS/브라우저 DOM (0) | 2023.07.07 |
| [DAY 5] JavaScript 핵심 개념과 주요 문법 (0) | 2023.07.06 |
| [DAY4] JavaScript 배열/객체 (0) | 2023.07.05 |
| [DAY3] 과제 - 간단한 웹앱 만들기(Fork, Pull requests) (1) | 2023.07.04 |