[JavaScript] 모듈 패턴 (Module Pattern)

2025. 3. 6. 15:46·JavaScript
728x90

JavaScript 의 모듈 패턴 (Module Pattern)

  • 모듈 패턴 : 정보 은닉 (Encapsulation) 을 활용해 코드의 구조를 정리하는 디자인 패턴 중 하나
    • 전역 변수 오염 방지 : 네임스페이스 충돌 방지
    • 데이터를 안전하게 보호하여 필요한 부분만 외부에 노출 가능 : 캡슐화(Encapsulation)
    • 코드 재사용성 용이, 유지보수 용
    • ES6 의 모듈 (import/export) 등장 전까지는 주로 IIFE (즉시 실행 함수 표현) 을 이용해 모듈화하는 방식 사용
  • 예시
const ModuleTest = (function () {
  // private 변수 및 함수
  let privateVar = "private 변수 : 외부에서 접근 불가";
  
  function privateFunction() {
    console.log("private 함수 : 외부에서 접근 불가");
  }
  
  const publicVar = "public 변수 : 외부에서 접근 가능";

  // 공개할 메서드 및 변수
  return {
  	publicVar: publicVar,
    publicFunction: function () {
      console.log("public 함수 : 외부에서 접근 가능");
      console.log("privateVar 출력 : " + privateVar);
    },
  };
})();

console.log(ModuleTest.publicVar); // public 변수 : 외부에서 접근 가능
ModuleTest.publicFunction(); // public 함수 : 외부에서 접근 가능
			   // privateVar 출력 : private 변수 : 외부에서 접근 불가

console.log(ModuleTest.privateVar); // undefined
ModuleTest.privateFunction(); // 에러 발생 (외부 접근 불가)
  • 즉시 실행 함수 표현 (IIFE) 를 활용하여 private 데이터 보호
  • return 문을 통해 외부에 공개할 속성 및 메서드만 노출

 

즉시 실행 함수 표현식 (IIFE : Immediately Invoked Function Expression)

  • 즉시 실행 함수 : 정의되자마자 즉시 실행되는 함수로, 함수를 선언하고 그 즉시 해당 함수를 호출하는 방식으로 작동
    • 정의되자마자 즉시 실행
    • 전역 네임스페이스 오염 방지
    • 모듈 패턴에서 캡슐화 용도로 사용

IIFE 기본 문법

(function () {
  console.log("즉시 실행되는 함수");
})();
  • `function () { ... }` : 익명 함수
  • `()` 로 감싸는 이유 : 함수 선언과 실행을 동시에 하기 위해
  • 마지막 `()` : 즉시 실행을 의미
만약 `()` 로 감싸지 않으면 SyntaxError 발생 : 함수 선언문은 이름 필요

IIFE 활용 방법

  • 기본 IIFE (익명 함수)
(function () {
  console.log("기본 IIFE 실행");
})();
  • 화살표 함수 사용
(() => {
  console.log("화살표 함수 IIFE 실행");
})();
  • 매개변수가 있는 IIFE
(function (name) {
  console.log(`Hello, ${name}!`);
})("Cyyy");
  • 반환값이 있는 IIFE
const message = (function () {
  return "즉시 반환";
})();

console.log(message); // 즉시 반환

 

IIFE 사용 이유

(function () {
  let count = 0; // private 변수
  console.log("초기 값:", count);
})();

console.log(count); // ReferenceError: count is not defined
  • 전역 변수 오염 방지 : IIFE 는 변수를 함수 내부에서만 사용하도록 제한 가능
    • count 변수는 IIFE 내부에 있으므로 외부에서 접근 불가 → 전역 변수 오염 방지
const CounterModule = (function () {
  let count = 0;

  function increment() {
    count++;
    console.log("Count:", count);
  }

  return {
    increment,
  };
})();

CounterModule.increment(); // Count: 1
CounterModule.increment(); // Count: 2
console.log(CounterModule.count); // undefined (private 변수 보호됨)
  • 모듈 패턴에서 사용 (정보 은닉)
    • count 변수는 외부에서 직접 접근 불가, `increment()` 메서드 통해서만 조작 가능
for (var i = 0; i < 3; i++) {
  setTimeout(() => console.log(i), 1000);
}
// 결과: 3, 3, 3 (의도한 0, 1, 2가 아님)
// setTimeout 은 비동기 함수로, 루프가 끝난 후 i 값이 3이 된 상태에서 실행


for (var i = 0; i < 3; i++) {
  (function (index) {
    setTimeout(() => console.log(index), 1000);
  })(i);
}

// 결과: 0, 1, 2 (의도한 대로 실행)
  • 비동기 코드에서 사용
    • IIFE 를 활용 시 각 i의 값을 개별적으로 저장하는 클로저 (Closure) 역할 수행

 

ES6 모듈 (ES6 Module)

  • ES6 모듈 : JavaScript 에 공식적으로 도입된 모듈 시스템으로, `import` 와 `export` 키워드를 활용해 코드 모듈화 가능
    • 전역 네임스페이스 오염 방지
    • 코드 재사용 용이
    • 선택적으로 import 하여 사용 가능

ES6 모듈 기본 문법

  • `export` : 모듈에서 코드 내보내기
// math.js
export const pi = 3.14159;

export function add(a, b) {
  return a + b;
}

export function multiply(a, b) {
  return a * b;
}
  • `import` : 모듈에서 코드 가져오기
// main.js
import { pi, add, multiply } from "./math.js";

console.log(pi); // 3.14159
console.log(add(2, 3)); // 5
console.log(multiply(4, 5)); // 20

ES6 모듈 활용

  • `export default` : 모듈에서 하나의 기본 값 내보낼 때 사용, `import` 시 이름을 자유롭게 정할 수 있음
// logger.js
export default function log(message) {
  console.log(`[LOG]: ${message}`);
}

// app.js
import log from "./logger.js"; // import할 때 {} 없이 사용

log("Hello, world!"); // [LOG]: Hello, world!
  • `import * as` : `export` 된 것을 한 객체로 가져올 수 있음
// main.js
import * as math from "./math.js";

console.log(math.pi); // 3.14159
console.log(math.add(10, 20)); // 30
console.log(math.multiply(5, 6)); // 30
  • `import { as }` : 별칭 (Alias) 를 이용해 `import`
// main.js
import { add as sum, multiply as product } from "./math.js";

console.log(sum(5, 5)); // 10
console.log(product(3, 4)); // 12

브라우저에서 ES6 모듈 사용

  • 브라우저에서 `<script>` 태그 내에서 모듈을 사용하기 위해서는 `type="module"` 추가 필요
<!DOCTYPE html>
<html lang="ko">
<head>
  <meta charset="UTF-8">
  <title>ES6 Modules</title>
</head>
<body>
  <script type="module" src="main.js"></script>
</body>
</html>

 

 

IIFE 모듈 패턴 vs ES6 모듈

  • 모듈 패턴은 ES6 모듈이 등장하기 전에 널리 사용, 현재는 ES6 모듈이 표준
    • 브라우저 환경에서 모듈 번들러 없이 사용할 경우 모듈 패턴이 유용할 수 있음
  모듈 패턴 ES6 모듈
사용 방식 IIFE 와 객체 반환 `import`, `export` 사용
private 변수 보호 가능 불가능 (export 시 외부에서 접근 가능)
브라우저 지원 모든 환경 모듈 지원 환경에서만 가능
유지보수성 비교적 제한적 더 구조적인 관리 가능

 

 


JavaScript의 모듈 패턴은 코드의 캡슐화와 전역 네임스페이스 오염 방지를 위해 유용한 패턴이지만,
ES6 모듈의 등장으로 기본적인 모듈 시스템이 제공되므로 최신 프로젝트에서는 ES6 모듈 활용하는 것이 적절.

 

728x90
저작자표시 비영리 변경금지 (새창열림)

'JavaScript' 카테고리의 다른 글

[JavaScript] 프로토타입 (Prototype) 성능 최적화  (1) 2025.03.14
[JavaScript] 프로토타입 (Prototype) 활용 방법  (0) 2025.03.14
[JavaScript] 프로토타입 (Prototype) 기본 개념  (1) 2025.03.13
[JavaScript] 자바스크립트 ES6 문법 정리  (1) 2025.03.13
[JavaScript] 익명 함수, 화살표 함수  (1) 2025.03.07
'JavaScript' 카테고리의 다른 글
  • [JavaScript] 프로토타입 (Prototype) 활용 방법
  • [JavaScript] 프로토타입 (Prototype) 기본 개념
  • [JavaScript] 자바스크립트 ES6 문법 정리
  • [JavaScript] 익명 함수, 화살표 함수
cyyy
cyyy
    250x250
  • cyyy
    Dev Log
    cyyy
  • 전체
    오늘
    어제
    • 분류 전체보기 (71)
      • Web | Network (14)
      • JavaScript (17)
      • Node.js (13)
      • Java | Spring (17)
        • GitHub Clone Project (6)
      • DB (4)
      • Linux (4)
      • AWS (2)
      • IDE (0)
  • 최근 글

  • 인기 글

  • 태그

    spring boot
    Linux
    스프링
    JavaScript
    prototype
    Database
    promise
    node.js
    자바스크립트
    네트워크
    프로토타입
    노드
    Spring
    비동기
    Java
    github clone
    db
    프로토콜
    bcrypt
    Network
  • 링크

    • Notion Log
  • hELLO· Designed By정상우.v4.10.3
cyyy
[JavaScript] 모듈 패턴 (Module Pattern)
상단으로

티스토리툴바