Computer >> 컴퓨터 >  >> 프로그래밍 >> JavaScript

JavaScript 클로저와 중첩 함수의 차이점 완벽 정리

JavaScript 클로저(Closure)란?

JavaScript에서 모든 함수는 클로저처럼 동작합니다. 클로저란 함수가 호출될 때 자신이 선언된 스코프(범위)를 사용하는 함수를 의미합니다. 즉, 함수가 호출된 위치의 스코프가 아니라, 함수가 정의된 시점의 스코프를 기억하고 참조합니다.

다음 예제를 통해 클로저의 동작 방식을 확인해 보겠습니다.

<!DOCTYPE html>
<html>
   <body>
      <h2>JavaScript Closures</h2>
      <script>
         var p = 20;
         function a() {
            var p = 40;
            b(function() {
               alert(p);
            });
         }
         function b(f) {
            var p = 60;
            f();
         }
         a();
      </script>
   </body>
</html>

위 예제에서 익명 함수는 변수 p를 참조할 때, 실제로 호출된 함수 b 내부의 값(60)이 아니라, 자신이 선언된 함수 a 내부의 값(40)을 사용합니다. 이처럼 함수가 정의된 환경의 스코프를 유지하는 것이 바로 클로저의 핵심 원리입니다.

JavaScript 중첩 함수(Nested Function)란?

JavaScript 1.2부터는 함수 정의를 다른 함수 내부에 중첩하여 작성할 수 있습니다. 다만, 함수 정의는 반복문이나 조건문 안에는 위치할 수 없다는 제한이 있습니다. 이러한 제약은 function 문을 사용하는 함수 선언(function declaration)에만 적용되며, 함수 표현식에는 해당되지 않습니다.

예제

아래 예제를 실행하면 중첩 함수를 구현하는 방법을 직접 확인할 수 있습니다.

<html>
   <head>
      <script>
         function hypotenuse(a, b) {
            function square(x) {
               return x * x;
            }
            return Math.sqrt(square(a) + square(b));
         }

         function secondFunction() {
            var result;
            result = hypotenuse(5, 4);
            document.write(result);
         }
      </script>
   </head>
   <body>
      <p>아래 버튼을 클릭하여 함수를 호출해 보세요.</p>
      <form>
         <input type="button" onclick="secondFunction()" value="함수 호출">
      </form>
      <p>함수 내부의 매개변수 값을 다르게 변경한 후 다시 시도해 보세요.</p>
   </body>
</html>

위 예제에서 hypotenuse 함수 내부에 정의된 square 함수가 중첩 함수입니다. square 함수는 외부에서 직접 접근할 수 없으며, 오직 hypotenuse 함수 내부에서만 사용됩니다. 이렇게 중첩 함수를 활용하면 불필요한 전역 스코프 오염을 막고 코드의 캡슐화를 높일 수 있습니다.

클로저와 중첩 함수의 핵심 차이

두 개념을 정리하면 다음과 같습니다.
- 중첩 함수: 단순히 함수 안에 또 다른 함수가 정의된 구조를 의미합니다.
- 클로저: 중첩 함수가 외부 함수의 변수와 스코프에 접근할 수 있게 해주는 동작 방식을 의미합니다.

즉, 중첩 함수는 코드 작성 형태에 관한 개념이고, 클로저는 그 구조가 만들어내는 스코프 체인의 특성에 관한 개념입니다. JavaScript에서는 모든 함수가 클로저로 동작하기 때문에, 중첩 함수는 자연스럽게 외부 함수의 변수를 기억하고 접근할 수 있습니다.