공부 정리/You Don't Know Js

[YDKJ] Scope & Closures - The Module Pattern

경적필패. 2023. 6. 5. 03:30
반응형

요약

이 챕터에서는 코드 구성 패턴 중 하나인 모듈을 탐구할 것임.

 

Encapsulation and Least Exposure (POLE)pole:최소노출원칙

  • 캡슐화의 목표는 공통된 목적을 제공하는 데이터와 함수를 함께 묶어 배치하는 것.
  • 비슷한 프로그램 조각을 함께 그룹화하는 것. 세부정보의 접근을 제한하는 것.

이러한 과정 속에서 코드의 조직성이 향상됨.=>유지보수 굿, 과도한 노출 방지.

이것이 js프로그램을 모듈로 구성하는 것에 대한 이점 중 일부임.

 

What Is a Module?

모듈은 관련된 데이터와 함수의 모음.

또한 상태를 가지고 있고, 시간이 지남에 따라 정보를 유지하고 업데이트함

 

Namespaces (Stateless Grouping)

// namespace, not module
var Utils = {
    cancelEvt(evt) {
        evt.preventDefault();
        evt.stopPropagation();
        evt.stopImmediatePropagation();
    },
    wait(ms) {
        return new Promise(function c(res){
            setTimeout(res,ms);
        });
    },
    isValidEmail(email) {
        return /[^@]+@[^@.]+\.[^@.]+/.test(email);
    }
};

이 코드처럼 데이터 없이 함수들을 그룹화한다면 이건 모듈이 아님

이건 그냥 기능을 모은 것뿐.=> 네임스페이스

 

Data Structures (Stateful Grouping)

// data structure, not module
var Student = {
    records: [
        { id: 14, name: "Kyle", grade: 86 },
        { id: 73, name: "Suzy", grade: 87 },
        { id: 112, name: "Frank", grade: 75 },
        { id: 6, name: "Sarah", grade: 91 }
    ],
    getName(studentID) {
        var student = this.records.find(
            student => student.id == studentID
        );
        return student.name;
    }
};

Student.getName(73);
// Suzy

이 코드에서 Student는 데이터를 다루고 있지만, 가시성을 제한하고 있지는 않음. 즉 POLE 측면에서 부족한 코드임.

이 코드는 모듈이라고 하기보다는 데이터 구조의 인스턴스가 맞음.

 

Modules (Stateful Access Control)

var Student = (function defineStudent(){
    var records = [
        { id: 14, name: "Kyle", grade: 86 },
        { id: 73, name: "Suzy", grade: 87 },
        { id: 112, name: "Frank", grade: 75 },
        { id: 6, name: "Sarah", grade: 91 }
    ];

    var publicAPI = {
        getName
    };

    return publicAPI;

    // ************************

    function getName(studentID) {
        var student = records.find(
            student => student.id == studentID
        );
        return student.name;
    }
})();

Student.getName(73);   // Suzy

이것이 모듈의 예시임. (2000년대 클래식한 방식)

함수를 반환하고, 클로저를 이용해 변수에 접근한다.

 

Classic Module Definition

클래식 모듈을 만드는 요소

  • 외부 스코프가 있어야 함.
  • 모듈의 내부 범위에 상태가 최소한 하나는 있어야 함.
  • 최소한 하나의 함수를 반환해야 함.

=> 자세한 건 appendix A에서

 

Node CommonJS Modules

commonjs 모듈은 파일이기반이며, 한 파일당 하나의 모듈이다.

module.exports.getName = getName;

// ************************

var records = [
    { id: 14, name: "Kyle", grade: 86 },
    { id: 73, name: "Suzy", grade: 87 },
    { id: 112, name: "Frank", grade: 75 },
    { id: 6, name: "Sarah", grade: 91 }
];

function getName(studentID) {
    var student = records.find(
        student => student.id == studentID
    );
    return student.name;
}

레거시 코드에선 module를 빼먹고 exports만 쓰는 경우도 있지만, 명확성을 위해 module를 반드시 써줄 것.

 

commonjs 모듈은 싱글톤 인스턴스처럼 작동함. => 여러 번 require해도 여전히 단일 모듈 인스턴스에 대한 참조만 받음

 

Modern ES Modules (ESM)

ES모듈도 마찬가지로 파일기반이며, 싱글톤임.

commonjs랑 다르게 export를 이용해 공개 api에 포함시킴.

 

export vs export default 방식이 있는데,

default를 사용하면 import 할 때 원하는 이름으로 가져올 수 있고,

그냥 export를 사용하면 정해진 이름으로 가져와야 한다. (as를 쓸 수 있긴 함)

 

 

 

느낀 점

이미 js의 모듈화 방식에 익숙해져 프로젝트를 진행했던 나에게, 크게 얻어갈 내용은 없었다.

그러나 데이터 없이 함수를 그룹화한다면 모듈화가 아니다?? 이건 처음 알았다.

 

 

 

 

 

 

 

반응형