JS 클로저란?

Junho Yun·2023년 3월 26일
1
post-thumbnail

클로저란?

JavaScript에서 클로저는 외부 함수가 반환된 후에도 외부 어휘 환경에 액세스할 수 있는 함수입니다. 간단히 말해서 클로저는 함수가 다른 함수 내에서 정의될 때 생성되며 내부 함수는 외부 함수가 실행을 완료한 후에도 외부 함수의 변수와 매개변수에 액세스할 수 있습니다.

함수가 다른 함수 내에서 정의되면 클로저를 통해 외부 함수의 변수 및 매개변수에 액세스할 수 있습니다. 이렇게 하면 외부 함수가 실행을 완료하고 반환된 경우에도 내부 함수가 이러한 변수에 대한 액세스를 유지할 수 있습니다. 이는 데이터와 동작을 캡슐화하고 전용 변수와 메서드를 만드는 데 유용할 수 있습니다.

코드 예시

JavaScript에서 클로저를 생성하려면 다른 함수 내부에 함수를 정의하고 내부 함수를 값으로 반환할 수 있습니다. 예를 들면 다음과 같습니다.

function outerFunction(x) {
  function innerFunction(y) {
    return x + y;
  }
  return innerFunction;
}

const closure = outerFunction(3);
console.log(closure(4)); // Output: 7

이 예에서 outerFunction은 x 매개변수를 사용하고 y 매개변수를 사용하는 내부 함수 innerFunction을 정의합니다. 내부 함수는 x와 y의 합을 반환합니다. 'outerFunction'은 내부 함수를 값으로 반환합니다.

outerFunction(3)을 호출하면 x가 3으로 설정된 내부 함수를 반환합니다. 이 함수를 변수 closure에 저장합니다. 그런 다음 closure(4)를 호출하여 x 값 3에 4를 더하고 7을 반환합니다.

내부 함수 innerFunction은 클로저를 통해 외부 함수 outerFunction의 x 값에 액세스할 수 있습니다. 이렇게 하면 외부 함수가 실행을 완료한 후에도 내부 함수가 x 값에 대한 액세스를 유지할 수 있습니다.

활용법

캡슐화

캡슐화: 클로저는 개체 외부에서 액세스하거나 수정할 수 없는 개체 내에서 개인 변수 및 메서드를 만드는 데 사용할 수 있습니다. 이는 데이터와 동작을 캡슐화하는 데 도움이 되며 재사용 가능한 코드를 만드는 데 유용할 수 있습니다.

function counter() {
  let count = 0;
  return {
    increment() {
      count++;
    },
    decrement() {
      count--;
    },
    getCount() {
      return count;
    }
  }
}

const myCounter = counter();
myCounter.increment();
console.log(myCounter.getCount()); // Output: 1

이 예에서 counter 함수는 increment, decrement 및 getCount의 세 가지 메서드가 있는 객체를 반환합니다. count 변수는 counter 함수의 클로저 내에서 정의되므로 객체 외부에서 액세스할 수 없습니다. 이렇게 하면 increment 및 decrement 메소드를 통해서만 수정할 수 있고 getCount 메소드를 통해서만 액세스할 수 있는 개인 변수가 생성됩니다.

콜백

콜백: 클로저는 부모 함수의 변수에 대한 액세스를 유지하는 콜백을 만드는 데 사용할 수 있습니다. 이는 콜백이 실행되기 전에 변수가 변경될 수 있는 비동기 코드에 유용할 수 있습니다.

function doSomethingAsync(callback) {
  const result = 42;
  setTimeout(function() {
    callback(result);
  }, 1000);
}

doSomethingAsync(function(result) {
  console.log(result); // Output: 42
});

이 예에서 doSomethingAsync 함수는 콜백 함수를 인수로 사용합니다. 이 함수는 클로저 내에 result 변수를 생성하고 setTimeout을 사용하여 result를 인수로 1초 후에 콜백 함수를 실행합니다. 콜백 함수는 비동기적으로 실행되더라도 클로저를 통해 result 변수에 대한 액세스를 유지합니다.

메모이제이션

메모이제이션: 클로저는 메모이제이션을 구현하는 데 사용할 수 있습니다. 메모이제이션은 값비싼 함수 호출의 결과를 캐싱하는 기술입니다. 이는 중복 계산을 방지하여 성능을 향상시키는 데 도움이 될 수 있습니다.

function memoize(func) {
  const cache = {};
  return function(...args) {
    const key = JSON.stringify(args);
    if (cache[key]) {
      return cache[key];
    } else {
      const result = func(...args);
      cache[key] = result;
      return result;
    }
  }
}

function fibonacci(n) {
  if (n <= 1) {
    return n;
  }
  return fibonacci(n - 1) + fibonacci(n - 2);
}

const memoizedFibonacci = memoize(fibonacci);
console.log(memoizedFibonacci(10)); // Output: 55
console.log(memoizedFibonacci(10)); // Output: 55 (cached result)

이 예제에서 memoize 함수는 func 함수를 인수로 사용하고 func 결과를 cache 개체에 캐시하는 클로저를 반환합니다. 클로저는 JSON.stringify 메서드를 사용하여 각 인수 집합에 대한 고유 키를 만들고 결과가 이미 저장되어 있는지 캐시를 확인합니다. 결과가 캐시에 있으면 클로저는 이를 반환합니다. 그렇지 않은 경우 인수로 func를 호출하고 결과를 캐시에 저장한 다음 반환합니다.

memoizedFibonacci 함수는 fibonacci 함수로 memoize를 호출하여 생성됩니다. memoizedFibonacci가 인수와 함께 호출되면 먼저 캐시를 확인하여 결과가 이미 계산되었는지 확인합니다. 그렇다면 캐시된 결과가 반환됩니다.

profile
의미 없는 코드는 없다.

0개의 댓글