본문 바로가기

JAVASCRIPT

함수형 프로그래밍

함수형 프로그래밍

고차 함수 (Higher-order Function)

함수를 인수로 받는 함수, 함수를 반환하는 함수를 말하며, 다른 함수의 인수로 넘겨지는 함수를 콜백(callback)이라고 부르기도 함

// 함수를 인수로 받는 함수
function func2(f) {
  f();
}

// 함수를 반환하는 함수
function func1() {
  return function() {};
}

클로저 (Closure)

바깥 스코프에 있는 변수를 가져다 사용하는 함수와 변수가 저장되는 저장소를 클로저라 부름
클로저의 성질은 데이터를 숨기고 정해진 방법을 통해서만 데이터에 접근할 수 있도록 제한을 두는데 활용

const arr = [];

for (let i = 0; i < 10; i++) {
  // 여기서 만들어진 함수는 바깥 스코프에 있는 변수 `i`를 사용
  arr.push(function() {
    return i;
  });
}

// for 루프의 실행은 끝났지만, 루프 안에서 만들어진 함수가 배열에 저장
// 배열 안에 들어있는 함수를 통해, 해당 함수가 만들어진 시점의 변수 `i`를 사용
console.log(arr[2]()); // 2
console.log(arr[5]()); // 5
// 데이터를 숨기는 방법
function makeCounter(x = 1) {
  return function() {
    return x++;
  }
}
// `x`를 직접 변경할 수 있는 방법이 없음

const counter = makeCounter();
console.log(counter()); // 1
console.log(counter()); // 2

화살표 함수와 고차 함수

화살표 함수 문법을 이용하면, 적은 양의 코드만 사용해서 고차 함수를 만들 수 있음

const makeAdder = x => y => x + y;

const add2 = makeAdder(2);
add2(3); // 5

재귀 함수 (Recursive Function)

자기 자신을 호출하는 함수를 뜻함

function func() {
    func();
}

루프와 재귀 함수

루프는 재귀함수를 통해 다시 구현될 수 있으며, 코드의 의미가 명확해지고 코드의 길이를 줄일 수 있음

// 루프로 구현된 팩토리얼
function factorialLoop(n) {
  let result = 1;
  for (let i = 2; i <= n; i++) {
    result *= i;
  }
  return result;
}

// 재귀 함수로 구현된 팩토리얼
function factorialRec(n) {
  return n <= 1 ? 1 : n * factorialRec(n - 1);
}

분할 정복 (Divide and Conquer)

문제를 작은 부분 문제로 나누어서 푼 뒤, 그 결과를 합치는 식으로 알고리즘을 작성하는 기법
분할 정복 기법을 활용하는 알고리즘 중 대표적인 예로 병합 정렬(merge sort)을 들 수 있음

function mergeSort(arr) {
  // 입력된 배열의 길이가 1 이하이면 더 이상 재귀 호출을 하지 않음
  if (arr.length <= 1) return arr;

  // 배열을 절반으로 잘라 두 개의 작은 배열로 분할하고,
  // 두 작은 배열에 대해 재귀 호출을 수행함
  const slicer = Math.floor(arr.length / 2);
  const arr1 = mergeSort(arr.slice(0, slicer));
  const arr2 = mergeSort(arr.slice(slicer));

  // `arr1`, `arr2`는 **이미 정렬되어있는 상태**이므로,
  // 이 성질을 이용해 두 배열을 **정렬되어있는 큰 배열**로 합칠 수 있음
  const newArr = [];
  for (let i = 0, j = 0; i < arr1.length || j < arr2.length; ) {
    if (arr1[i] == undefined || arr1[i] > arr2[j]) {
      newArr.push(arr2[j]);
      j++;
    } else {
      newArr.push(arr1[i]);
      i++;
    }
  }

  // 큰 배열을 반환
  return newArr;
}

'JAVASCRIPT' 카테고리의 다른 글

내장 객체 및 생성자  (0) 2020.07.30
연산자  (0) 2020.07.29
참조(Reference)  (0) 2020.07.28
객체  (0) 2019.07.25
제어 구문  (0) 2019.07.23