First-class citizen, higher order function

holang-i·2021년 3월 16일
0
post-thumbnail

일급객체: First-class citizen

자바스크립트에는 first-class, 일급객체가 존재한다.

자바스크립트에서 특별한 취급을 받는것을 가리켜서 일급 객체('first-class citizen')라고 부른다.

일급 객체에서 하나가 바로 함수이다.


함수

  • 변수에 할당(assignment)을 할 수 있다.
  • 다른 함수의 인자(arguments)로 전달될 수 있다.
  • 다른 함수의 결과로서 리턴될 수 있다.

위의 3가지를 풀어보면 함수를 데이터(string, number, boolean, array, object)들을 다루듯이 다룰 수 있음을 의미한다.

함수를 변수에 저장해서 사용이 가능하고, 배열이나 객체의 속성값으로 주는것도 가능하다.

함수 표현식(function expression)을 사용해서 함수를 변수에 할당할 수 있다. 함수 표현식은 호이스팅이 되는 함수 선언식과는 다르게 호이스팅이 적용되지 않는다.


함수 표현식을 사용하여 변수에 함수를 할당

아래의 코드를 통해 변수에 함수를 할당하는 함수 표현식에 대해 알아볼 것이다.

  • 자바스크립트에서 함수는 일급 객체이기 때문에 변수에 함수를 저장할 수 있다.
  • 함수 표현식은 할당 전에는 절대 사용할 수 없다!
// 아래의 코드는 곱하기 기능을 하는 함수를 변수 multiply에 담는 과정을 나타낸다.
const multiply = function(num1, num2) {
  return num1 * num2; 
}

// multiply라는 변수에는 뭐가 저장되어 있을까?
// 숫자 2개를 곱하는 기능을 하는 함수가 저장되어 있다.
// 그러면, multiply에는 함수가 저장되어 있으니 `일급 객체`라고 부를 수 있다.
// multiply에는 함수가 저장되어 있으므로, 함수를 호출하여 사용할 수 있다.
let result = multiply(124, 35);
console.log(result); // 4340


함수 선언식을 사용하면, 함수가 맨 아래에서 선언되어 있고, 함수의 실행을 코드의 맨 위에서 한다해도 문제가 발생하지 않고, 함수가 실행되게 된다.

이것이 가능한 이유는 호이스팅 때문이다.

어느 위치에서 함수를 선언해서 실행할 수 있는 함수의 선언식에 비해 함수 표현식은 함수의 할당과 함수의 실행 위치가 매우 중요해서 코드를 보고 어떤 함수가 밑에서 쓰이겠구나 예측을 할 수 있다.

그리고, 함수 표현식을 사용하게되면 함수를 변수에 저장해서 사용할 수 있고,
변수에 저장된 데이터는 또 함수의 인자로 전달할 수 있다.

또는 함수 안에서 리턴값으로도 사용할 수 있기 때문에 이 개념을 활용하면 자바스크립트의 고차함수(higher order function)로 연결될 수 있다.


고차 함수

고차 함수(higher order function)는 함수를 인자(arguments)로 받거나 함수를 리턴하는 함수를 뜻한다.

콜백 함수에 대해서 알아보자.
콜백 함수(callback function)는 다른 함수(caller)의 인자(arguments)로 전달되는 함수를 말한다.


콜백 함수를 전달받은 함수는 전달받은 함수를 호출할 수 있다.
caller는 조건에 따라 콜백 함수의 실행 여부를 결정할 수 있다. 심지어 전달받은 함수를 여러번 반복해서 실행할 수도 있다.

콜백 함수라는 이름이 붇은 것을 살펴보면, 어떠한 작업이 끝난 뒤, 완료된 다음에 호출되는 경우가 많아서 콜백(답신)이라는 이름이 붙여졌다고 한다.


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

function divideFive(num) {
  return num / 5;
}

function divideNumber(otherFunction, num) {
  return otherFunction(num); 
}

// 위의 divideNumber 함수는 첫 번째 파라미터로 함수를 받고 있기 때문에 고차함수이다.
// divideNumber 함수의 첫 번째 인자 otherFunction에 함수가 들어오면
// otherFunction은 divideNumber 함수의 콜백 함수이다!

// 아래의 divideNumber 함수의 첫 번째 인자로 들어가는 divideFive는 divideNumber 함수의 콜백 함수이다!
let result = divideNumber(divideFive, 392);
console.log(result); // 78.4


2. 함수를 리턴하는 경우

// 아래의 multiply 함수는 다른 함수를 리턴하는 고차 함수이다.
// multiply 함수는 매개변수로 값 1개를 입력받아서 익명함수를 리턴하고 있다.
// 리턴되는 익명 함수를 살펴보면, 매개변수로 값 1개를 입력받아서 바깥에 있는 multiply 함수의 매개변수 num1과 곱한 값을 리턴하고 있다.
function multiply(num1) {
  return function(num2) {
    return num2 * num1;
  };
}

// multiply(8)는 함수 --> 함수 호출 연산자 ( )를 사용할 수 있다. 
let result = multiply(8)(7); //
console.log(result); // 

// multiply 함수가 리턴하는 함수를 변수에 저장할 수 있다.
// 함수를 변수에 할당하는 것이 가능한 이유는 자바스크립트에서는 함수는 일급 객체이기 때문이다!!!
const multiplication10 = multiply(10);

// multiplication10에는 function(num2) { return num2 * 10; }; 이라는 함수가 할당되어 있다.
// 그렇기 때문에 multiplication10 함수에 5라는 인자값을 넣어주면
// 결과적으로 5 * 10이라는 연산이 일어나고 그 결과인 50을 리턴하게 된다.
let result2 = multiplication10(5);
console.log(result2); // 50


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

// powerMinus는 고차 함수이다!
// powerMinus의 매개변수로 들어오는 otherFunction은 함수 powerMinus의 콜백 함수이다!
// power 함수는 powerMinus 함수의 콜백으로 전달된다.
function power(num) {
  return Math.pow(num, 2);
}

function powerMinus(minusNum, otherFunction) {
  const involution = otherFunction(minusNum);
  return function(num) {
    return num - involution;
  }
}

// powerMinus(5, power)는 함수이기 때문에
// 함수 호출 ( )을 사용할 수 있다.
let result = powerMinus(5, power)(7); // -18

// powerMinus 함수가 리턴하는 함수를 변수에 저장할 수 있다. --> 일급객체이다.
const result9 = powerMinus(9, power);
result9(8); // 73

0개의 댓글