고차함수는 전달인자(argument)로 함수를 넘겨줄 수 있다.
고차 함수의 전달인자로 넘겨주는 함수를 콜백 함수(Callback function)라고 한다.
고차 함수는 다른 함수를 리턴할 수 있다.
고안 해난 논리학자 하스켈 커리의 이름을 따, 커링 함수라고 한다.
콜백 함수를 전달받은 고차 함수는 함수 내부에서 이 콜백 함수를 호출할 수 있고, 조건에 따라 콜백 함수의 실행 여부를 결정할 수도 있다. 아예 호출하지 않을 수도 있고, 여러번 실행 할수도 있다. 특정 작업 완료 후 호출하는 경우도 있다.
고차 함수를 이해하기 위해선 메서드가 어떤 식으로 만들어졌는지 생각해보는 것이 공부하는 데 도움이 될 것이다.
_.each = function (collection, iteratee) {
if (Array.isArray(collection)) {
for (let idx = 0; idx < collection.length; idx++) {
iteratee(collection[idx], idx, collection);
}
}
if (!Array.isArray(collection)) {
for (let key in collection) {
iteratee(collection[key], key, collection);
}
}
};
_.each()는 인자를 두개 받는다. collection는 배열이나 객체, iteratee는 각 요소마다 실행할 함수.
이제부터는 이미 만든 _.each() 함수를 가지고 다른 메서드를 만들 수 있다.
_.indexOf = function (arr, target) {
let result = -1;
_.each(arr, function (item, index) {
if (item === target && result === -1) {
result = index; `
}
});
return result;
};
_.each()에 들어가는 인자는 순서대로 _.each()에 있는 iteratee 함수에 넣을 수 있다. iteratee 함수 인수에 item과 index라는 별도의 이름으로 적었지만, 순서대로 collecion[idx], idx의 역할을 한다.
안에 함수는 조건문이 달려있고 반복을 한다.
_.indexOf에서 넣은 두번째 인자인 target이 중복될 때, -1이 아니라 인덱스를 출력하는 함수다.
.filter()라는 메서드는 어떠한 조건식을 만족시킨 요소들만 새 배열로 리턴하는 함수라고 할 수 있다.
_.filter = function (arr, test) {
// TODO: 여기에 코드를 작성합니다.
let result = [];
_.each(arr, function (item, idx, arr) {
if (test(arr[idx])) {
result.push(arr[idx]);
}
});
return result;
};
arr의 각test라는 조건식이 true면, result에 push하고 return한다.
.map()는 각 요소마다 함수를 실행하고 결과값을 새 배열에 넣어 리턴한다.
_.map = function (arr, iteratee) {
let result = [];
_.each(arr, function (item) {
const funcResult = iteratee(item);
result.push(funcResult);
});
return result;
};
iteratee 함수는 익명 함수. 각 요소마다 iteratee 함수를 실행해서 리턴한 값을 acc를 해줘서 리턴된 값을 acc에 누적해 iteratee 함수를 반복실행한다.
_.reduce = function (arr, iteratee, initVal) {
// TODO: 여기에 코드를 작성합니다.
//
if (initVal || initVal === 0) {
let acc = initVal;
_.each(arr, function (ele, idx, arr) {
acc = iteratee(acc, ele, idx, arr);
});
return acc;
}
if (!initVal) {
let acc = arr[0];
_.each(arr, function (ele, idx) {
if (idx > 0) {
acc = iteratee(acc, ele, idx, arr);
}
});
return acc;
}
};
이해하기 정말 힘들다. 예를 만들어 로직이 어떤 순서로 작동하는지 계속해서 이해하는 연습을 해야겠다.