17. 고차함수

Lia·2023년 5월 9일
0

고차함수

왜쓰는지?

추상화를 통한 효율성 증대

특징

변수에 할당(assignment)할 수 있다.
다른 함수의 전달인자(argument)로 전달될 수 있다.
다른 함수의 결과로써 리턴될 수 있다.
함수를 변수에 할당할 수 있기 때문에, 함수를 배열의 요소나 객체의 속성 값으로 저장할 수 있습니다. 함수를 데이터(string, number, boolean, array, object)처럼 다룰 수 있습니다.
함수를 전달인자로 받거나 함수를 리턴하는 함수를 고차함수라고 합니다.
그렇다면 함수의 전달인자로 전달되는 함수는? 콜백함수라고 한다.

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

// 변수 square에는 함수가 할당되어 있으므로 (일급 객체), 함수 호출 연산자 '()'를 사용할 수 있습니다.함수를 리턴하는 경우
output = square(7);
console.log(output); // --> 49

다른 함수를 인자로 받는 경우

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

function doubleNum(func, num) {
  return func(num);
}
// 함수 func는 함수 doubleNum의 콜백 함수입니다.
// 아래와 같은 경우, 함수 double은 함수 doubleNum의 콜백 함수입니다.

let output = doubleNum(double, 4);
console.log(output); // -> 8
 

실행순서
1. doubleNum 함수를 호출하고, double 함수를 첫 번째 인자 func로, 4를 두 번째 인자 num으로 전달합니다.
2. doubleNum 함수의 실행이 시작됩니다.
3. doubleNum 함수 내부에서 func(num)을 실행합니다. 여기서 func은 double 함수를 가리킵니다. 따라서, double(4)가 실행됩니다.
4. double 함수는 4 * 2의 결과인 8을 반환합니다.
5. doubleNum 함수는 double(4)의 반환값인 8을 반환합니다.
6. output 변수에 doubleNum 함수의 반환값인 8이 저장됩니다.
7. console.log(output)이 실행되고, 콘솔에 8이 출력됩니다.

함수를 리턴하는 경우

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(5)를 호출한 결과는 익명 함수입니다.
이후 3이라는 인자를 이용하여 반환된 익명 함수를 호출합니다.
이때 added 매개변수에는 5가 전달되어 클로저에 의해 값이 보존되며, num + added 계산을 수행하여 8이 반환됩니다.

살짝 이해가 안갈뻔했는데. . 먼저 adder(5)는 added 매개변수에 인자로 5을 전달하여 익명함수를 반환함
그 다음 3을 인자로 전달해서 반환된 익명함수를 호출함
리턴하는값은 8이 됨.

함수를 인자로 받고, 함수를 리턴하는 경우

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

익명함수를 호출할때 (3)이 num에 전달되는것!만 알면 까먹지않을듯하다. 익명함수가 헷갈린다.

문제풀이

문제 1
'Hello HoF!' 리턴하는 함수를 리턴해야 합니다.
입력
없음
출력
함수를 리턴해야 합니다.
주의 사항
리턴하는 함수의 입력값은 없습니다.

function returnFunction() { // 입력) 입력값은 없습니다.
  return function () { // 익명함수만들어서 리턴하는 함수
    return 'Hello HoF!';
  };
}
function returnFunction(){

}
/*
returnFunction() 함수를 호출함 -> returnFunction 함수가 실행됨 -> returnFunction은 'Hello HoF'문자열을 return해줌

'Hello HoF'를 리턴하는 함수인 function익명함수를 리턴하는 결과가 나오게 됨!
*/

문제에 접근하는 것이 아직 어렵다. ㅠㅠ 위 문제는 이렇게 접근을 했다. 
1. 문제를 먼저읽고 함수를 리턴한다는것을 인지
2. 입력을 보고 함수에 입력값이 없구나 인지
3. 출력을 확인함 문제와 같음

문제 2
함수와 수(num)를 입력받아 num에 함수를 적용(apply)한 결과를 리턴해야 합니다.
입력
인자 1 : func
number 타입을 입력받아 임의의 타입을 리턴하는 함수
인자 2 : num
number 타입의 정수 (num >= 0)
출력
주어진 함수의 리턴 타입을 따릅니다.
주의 사항
입력받은 함수가 어떤 일을 하는지는 중요하지 않습니다.

function functionParameter(func, num) {
return func(num)
}

/*
1. 문제를 먼저읽고 num에 함수를 적용/ 그 결과를 리턴
2. 입력을 보고 매개변수1은 number타입을 입력받아 리턴하는 func함수인것임/ return func(num)
3. 출력을 확인함 함수의 리턴타입을 따라야함.
*/

음.. func가 함수란느 것. functionParameter함수는 함수와 정수를 인자로 가지고있는 것이지..
그래서 func(num)이 되는 것이지. . 그것을 리턴하면 해결되는것이지 .. !
간단한것인데. . 이..문제를 보고 푸는것이.. 접근하는것이 어려워...

내장 고차 함수

JavaScript에는 기본적으로 내장된 고차 함수가 여럿 있습니다.
그중에서 배열 메서드들 중 일부가 대표적인 고차 함수에 해당합니다.

내장 고차 함수 filter 메서드

모든 배열의 요소 중에서 특정 조건을 만족하는 요소를 걸러내는 메서드
1) 걸러내는 기준이 되는 특정 조건은 filter 메서드의 전달인자로 전달됩니다.
2) 전달되는 조건은 함수의 형태입니다

예시 1
function aboveElghtten (number){
   return number > 18;
}
let number = [12, 5, 8, 22, 55].filter(aboveElghtten);
console.log(number); // [22, 55]

예시 2
let snacks = ['감자칩', '오징어칩' , '썬칩', '초코칩'];
const result = snacks.filter(snack => snack.length > 3);
console.log(result); //['오징어칩']

내장 고차 함수 map 메서드

  • 함수를 받아 특정기능을 시행하고 새로운 배열을 반환한다.
  • 매개변수로 전달된 함수의 첫 번째 인자로 배열의 현재 요소가 전달

map 활용 시, 아래 과정을 거친다.
1. 배열의 각 요소가
2. 특정 논리(함수)에 의해
3. 다른 요소로 지정(map) 됩니다.

const arr = [1, 2, 3];

// map 메소드 호출
const result = arr.map(function(item) {
  return item * 2;
});

console.log(result); // [2, 4, 6]

공부를 하면할수록 어떤게 어떤것을 참조하고 어떤것이 인자이고 콜백함수이고인지 헷갈린다. 이런것을 명확하게 알고있어야
코드를 분석하고 설명할때 잘 할수있는것이고 내것으로 만들수있을텐데 갈길이 멀다.

map() 메소드의 인자로 들어가는 함수는 콜백 함수!
(callback function)라고한다.

function(item) {
  return item * 2;
}

function(item)은 이 콜백 함수의 매개변수(parameter)!!

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

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

num이 어떻게 배열의 요소를 순회할수있는것인가?
이해가 안갔는데

이유는 map 메소드가 내부적으로 배열의 각 요소를 순회하면서 매개변수로 전달된 함수를 호출하는데, 이 때 매개변수로 전달된 함수의 첫 번째 인자로 배열의 현재 요소가 전달되기 때문!

내장 고차 함수 reduce 메서드

  • 초기값을 정할수있고, 정하지않으면 배열의 첫번째요소가 초기값

reduce 활용 시, 아래 과정을 거친다.
1. 배열의 각 요소를
2. 특정 방법(함수)에 따라
3. 원하는 하나의 형태로
4, 응축합니다. (reduction)

예시1
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 , 현재값이 cur 
예시2
const addAccCur = function (acc, cur) {
	return acc + cur;
};

let arr = [1, 2, 3, 4, 5, 6, 7];
let output = arr.reduce(addAccCur,1);
console.log(output); // 29
// 초기값이 acc, 배열의 첫요소가 cur
profile
https://lia-portfolio.vercel.app/

0개의 댓글