캡슐화(관련 정보와 동작 모음)와 가시성 통제가 모듈의 특징.
모듈은 관련 데이터, 함수(메소드) 모음집인데, public accessible details(public API
)과 숨겨진 private details를 구분하는 특징이 있다.
그리고 다른 특징은 stateful. 시간이 지나면서 해당 정보에 접근, 업데이트하는 기능으로 정보들을 유지한다.
데이터 없이 관련 함수들만 묶은 경우.
// Util이라는 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, stateful function but(캡슐화 충족),but not limiting 가시성.(POLE 면에서 부족)
// 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
클래식 모듈
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;//함수로 바로 return 가능.
// ************************
function getName(studentID) {
var student = records.find(
student => student.id == studentID
);
return student.name;
}
})();//IIFE, singleton. only need just one.
Student.getName(73); // Suzy
Student는 모듈 인스턴스로 단일 method(getName)가 있는 public API를 제공하여 메소드를 통해 숨겨진 정보에 접근가능.
변수와 함수는 기본적으로 비공개 상태고, publicAPI에 저장된 것들만 외부에서 사용가능하게끔 한다.
// module factory function, not singleton IIFE
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;
}
}
var fullTime = defineStudent();
fullTime.getName(73); // Suzy
클래식 모듈과 다르게, CommonJS 모듈은 파일마다 한 개.
module.exports.getName = getName;
//공용 API 무언가를 노출하기 위해
// module.exports 객체에 속성 추가
// ************************
//전역범위가 아닌 top-level scope.
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;
}
//다중 모듈을 넣고 싶다면
Object.assign(module.exports,{
// .. exports ..
});
// defining a new object for the API 위와같이 하자.
//module.exports = {
// ..exports..
//};
가져올 때,
//singleton 인스턴스로 작동하여 동일 모듈을 여러번 가져와도 공유된 모듈 인스턴스의 참조를 얻음
var Student = require("/path/to/student.js");//해당 모듈의 전 publicAPI에 대한 참조
Student.getName(73);
// Suzy
//일부 참조
var getName = require("/path/to/student.js").getName;
// or alternately:
var { getName } = require("/path/to/student.js");
CommonJS와 비슷(파일 기준, 모듈 인스턴스 singleton). 그러나 ESM은 기본적으로 엄격모드.
export, import 키 사용.
//export
//다른 블록 내부는 안됨.
export { getName };
//
export function getName(studentID) {
// ..
}
//defulat export
export default function getName(studentID) {
// ..
}//non-default is named exports
//import
//named import
import { getName } from "/path/to/students.js";
//as
import { getName as getStudentName } from "/path/to/students.js";
getStudentName(73);
//default export => import
import getName from "/path/to/students.js";
//named defualt mix!
import { default as getName, /* .. others .. */ } from "/path/to/students.js";
//namespace import, *는 export된 모든 것을 가져와 namespace아래에 저장.
import * as Student from "/path/to/students.js";