함수의 매개변수를 통해 다른 함수의 내부로 전달되는 함수를 콜백 함수라고 하며
매개변수를 통해 함수의 외부에서 콜백 함수를 전달받은 함수를
고차 함수(Higher-Order Function)라고 한다.
=> 따라서 JS에서 함수는 일급 객체
Example 1) 함수를 인자로 받는다는건...callback이란 느낌일까?
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
Example 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
커리함수
: 함수를 리턴하는 함수(ex2에서는 adder함수)
Example 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
메소드
는 객체에 들어있는 함수이다.
예를들어 arr.map을 쓰는데 사실은 arr.prototype.map 이고 arr["map"] 도 통한다.
여기서 prototype
은 원형객체라고 한다.
그리고 콜백 함수의 반환값들로 구성된 새로운 배열을 반환한다. 바꾸기 ! 이때 원본 배열은 인정되지 않는다.
arr.map(callback(currentValue[, index[, array]])[, thisArg])
Exmaple 4) 맵 메서드의 기본 사용법
let arr = [1, 2, 3, 4, 5]
let arr1 = arr.map(el => el * 3);
console.log(arr1); //[3, 6, 9, 12, 15]
콜백함수에 두번째 인자를 줄 경우 인덱스를 가져 온다.
Example5) 인덱스를 쓸 경우
let arr = [2, 4, 6]
let arr1 = arr.map((el, i) => `${i}번째 인덱스의 값은: ${el * 3} `)
console.log(arr1); //[ '0번째 인덱스의 값은: 6 ', '1번째 인덱스의 값은: 12 ', '2번째 인덱스의 값은: 18 ' ]
그리고 콜백 함수의 반환값이 true인 요소로만 구성된 새로운 배열을 반환한다. 거름망 ! 원본 배열 인정 안함.
arr.filter(callback(element[, index[, array]])[, thisArg])
Example 6) 필터 메서드의 기본 사용법
let arr = [1, '2', '5,', undefined];
let arr1 = arr.filter(el => typeof (el) === 'string');
console.log(arr1); //[ '2', '5,' ]
그리고 콜백 함수의 반환값을 다음 순회 시에 콜백 함수의 첫 번째 인수로 전달하면서 콜백 함수를 호출하여 하나의 결과값을 만들어 반환한다.
하나의 값으로 응축!
. 이떄 원본 배열은 변경되지 않는다.
Array.reduce( (acc, cur, index, arr ) => {결과값}, 초깃값)
acc
: 콜백반환값을 누적한다. 정하지 않으면 배열의 첫번쨰요소이다.
cur
: 현재값. i번째 인덱스의 값이다. 정하지 않으면 배열의 두번째 요소이다.
초깃값
: 보통 배열을 리턴하려면 [], 개게를 리턴하려면 {}형태를 준다. 정하지 않은경우 배열의 첫번쨰 요소가 초깃값이다.
Example 7) 요소의 중복횟수 구하기
const fruits = ['banana', 'apple', 'orange', 'orange', 'apple'];
const count = fruits.reduce((acc, cur) => {
// 순회 시 프로퍼티 값이 undefined이면 (acc[cur]이) 0으로 카운트하고 1을 더해줌
// 만약 프로퍼티 값이 존재하면 기존의 프로퍼티값에 1을 더해줌.
acc[cur] = (acc[cur] || 0) + 1;
return acc
}, {})
console.log(count); //{ banana: 1, apple: 2, orange: 2 }
Example) 사고 수준의 추상화의 예시
const data = [
{
gender: 'male',
age: 24,
},
{
gender: 'male',
age: 25,
},
{
gender: 'female',
age: 27,
},
{
gender: 'female',
age: 22,
},
{
gender: 'male',
age: 29,
},
];
Example)
unction getAverageAgeOfMaleAtOnce(data) {
const onlyMales = data.filter(function (d) {
// data.filter는 배열의 각 요소에 인자로 전달받은 함수를 적용하고,
// 그 결과가 true인 요소만을 갖는 배열을 리턴합니다.
return d.gender === 'male';
});
const numOfMales = onlyMales.length;
const onlyMaleAges = onlyMales.map(function (d) {
// onlyMales.map는 배열의 각 요소에 인자로 전달받은 함수를 적용하고,
// 각 결과를 요소로 갖는 배열을 리턴합니다.
return d.age;
});
const sumOfAges = onlyMaleAges.reduce(function (acc, cur) {
// onlyMaleAges.reduce는 배열의 각 요소에 인자로 전달받은 함수를 적용하고,
// 각 결과를 두 번째 인자로 전달받은 초기값(0)에 누적한 결과를 리턴합니다.
return acc + cur;
}, 0);
return sumOfAges / numOfMales;