[TIL] JS - 일급 객체로서 함수

12242 단어 TILTIL

Today I Learned

일급 객체 (First Class Object)

  • 자바스크립트에서 함수는 객체로 취급되기 때문에 다음과 같은 특성을 지닌다.
    • 리터럴로 생성 가능
    • 변수에 할당 가능
    • 함수의 인자로 전달 가능
    • 함수의 리턴값으로 리턴 가능
    • 동적으로 프로퍼티를 생성/할당 가능
  • 일급 객체로서의 함수란?
    • 함수의 인자로 전달, 변수에 대입 등이 가능한 객체

선언형 프로그래밍 (Declarative Programming) vs. 명령형 프로그래밍 (Imperative Programming)

  • 선언형 프로그래밍은 무엇(What)을 할 것인가에, 명령형 프로그래밍은 무엇을 어떻게(How)할 것인지에 초점을 둔 프로그래밍 패러다임이다.
    • 명령형 프로그래밍 : 알고리즘 O, 목표 X
    • 선언형 프로그래밍 : 알고리즘 X, 목표 O
  • 명령형은 특정 문제 하나를 해결하는 것에 초점을 두고 있어서 재사용성이 낮다.
  • 선언형은 추상화된 코드를 사용하여 재사용성을 높인다. 선언형 프로그래밍은 명령형 프로그래밍 방식보다 높은 수준의 추상화를 가능하게 한다.
  • 명령형 프로그래밍에는 절차적 프로그래밍, 객체지향 프로그래밍이 있다.
  • 선언형 프로그래밍에는 함수형 프로그래밍이 있다.
  • 자바스크립트에서는 절차적/객체지향/함수형 프로그래밍 모두 가능하다.
// Q. 다음 배열에서 5보다 큰 수만 담은 새로운 배열을 만들어라
const nums = [3, 5, 8, 1, 12, 7, 4, 9];

// Imperative Solution ----------
const numsBiggerThan5 = (arr) => {
  // Step 1. 리턴할 빈 배열 생성 
  const result = [];
  // Step 2. arr의 각 요소들을 for loop으로 조회
  for (let el of arr) {
    // Step 3. 5보다 큰 경우 result 배열에 push
    if (el > 5) {
      result.push(el);
    }
  }
  // Step 4. 새로 생성된 배열을 리턴
  return result;
}

// Declarative Solution ----------
const numsBiggerThan5 = (arr) => {
  // filter 함수의 로직을 몰라도 filter가 무엇을 하는 함수인지만 알면 됨
  return arr.filter(el => el > 5);
}

추상화

  • 복잡한 자료, 모듈, 시스템 등으로부터 핵심적인 개념 또는 기능을 간추려 내는 것
  • 어떤 함수를 사용할 때 그 함수 내부의 로직을 몰라도 사용할 수 있다. 예를 들 어 자바스크립트 내장 메서드인 filter()를 사용할 때 이 메서드의 로직은 모르지만 인자만 정확하게 전달하면 원하는 값을 얻을 수 있다. 이것이 추상화의 예로 로직(알고리즘)을 몰라도 무엇을 하고자 하는지(목표)만 명확하면 문제를 해결할 수 있다.
  • 추상화는 이면의 복잡한 로직을 고민하지 않게 하여 생산성을 향상시킨다.
  • 고차함수는 추상화의 수준을 사고(함수) 수준으로 끌어올린다.

고차함수/고계함수 (Higher Order Function)

  • 다른 함수를 인자로 전달 받거나 함수를 리턴하는 함수
  • 자바스크립트의 내장함수들 중에서 함수를 인자로 받는 filter(), map(), reduce()같은 함수들이 고차함수의 예다.
function isEven(num) {
  return num % 2 === 0;
}

function getEvenNums(arr) {
  return arr.filter(isEven);
}
// filter는 함수 isEven을 인자로 받고 있으므로 고차함수
// isEven은 filter의 전달인자로 사용되고 있으므로 콜백함수

콜백함수

  • 고차함수의 인자로 넘겨져 호출되는 함수
  • 명시적으로 호출되지 않고 등록만 되어 있다가 이벤트 발생 등 특정 시점에서 호출된다. (대표적으로 이벤트 핸들러 처리 함수)
// 타겟 요소
const scrollTopBtn = document.querySelector('#scroll-top-btn');

// 이벤트 리스너의 콜백함수로 사용할 scrollTop 함수
function scrollTop() {
  window.scrollTo({ top: 0, behavior: 'smooth' });
}

// 이벤트 리스너 생성 + 콜백함수 등록
scrollTopBtn.addEventListener('click', scrollTop);
// 타겟 요소에 클릭 이벤트가 발생하면 그때 콜백함수가 호출(실행)됨

커링함수 (Currying Function)

  • 함수형 프로그래밍을 활용한 함수로, n개의 인자를 받는 함수를 하나의 인자를 받는 n개의 함수 변환한 것을 말한다.
    • func(a, b, c) -> func(a)(b)(c)
  • 변하는 부분과 변하지 않는 부분을 나눠 변하지 않는 부분을 고정하고 변하는 부분을 열어두는 함수 추상화 기법이다.
  • 모든 인자를 받을 때까지 계속해서 함수를 생성한다.
  • 함수 인자수를 한 개로 줄여 재활용성을 높였다.
  • 함수 실행을 원하는 시점까지 미룰 수 있어서 비동기 관리에 용이하다.
const curry = (func) => {
	return function curriedFunc(...args) {
		if (args.length >= func.length) {
			return func(...args);
		} else {
			return (...args2) => curriedFunc(...args, ...args2);
		}
	};
};

함수 조합 (Function Composition)

  • 함수 조합은 둘 이상의 함수를 묶어 하나로 만드는 것
  • 커링과 함수 조합은 서로 관계되어 있으며 함께 쓰였을 때 시너지를 발생시킨다.
const compose = (...funcs) => (initialValue) => funcs.reduceRight((value, func) => func(value), initialValue);

좋은 웹페이지 즐겨찾기