Chapter 8: The Module Pattern - hochan222/Everything-in-JavaScript GitHub Wiki
Encapsulation and Least Exposure (POLE)
์บก์ํ๋ ์ข ์ข ๊ฐ์ฒด ์งํฅ (OO) ํ๋ก๊ทธ๋๋ฐ์ ์์น์ผ๋ก ์ธ์ฉ๋์ง๋ง ๊ทธ๋ณด๋ค ๋ ๊ธฐ๋ณธ์ ์ด๊ณ ๊ด๋ฒ์ํ๊ฒ ์ ์ฉ ํ ์ ์์ต๋๋ค. ์บก์ํ์ ๋ชฉํ๋ ํจ๊ป ๊ณตํต ๋ชฉ์ ์ ์ ๊ณตํ๋ ์ ๋ณด(๋ฐ์ดํฐ) ๋ฐ ๋์(ํจ์)์ ๋ฒ๋ค๋ง ๋๋ ๊ณต๋ ๋ฐฐ์น์ ๋๋ค.
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
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
์ดํ ๋ฒ์๊ฐ ์๋ํ๋ ๋ฐฉ์์ผ๋ก ์ธํด ์ธ๋ถ ๋ชจ๋ ์ ์ ํจ์ ๋ด์์ ๋ณ์์ ํจ์๋ฅผ ์ ์ํ๋ฉด ๊ธฐ๋ณธ์ ์ผ๋ก ๋ชจ๋ ๊ฒ์ด ๋น๊ณต๊ฐ๋ก ์ค์ ๋ฉ๋๋ค. ํจ์์์ ๋ฐํ ๋ ๊ณต์ฉ API ๊ฐ์ฒด์ ์ถ๊ฐ ๋ ์์ฑ ๋ง ์ธ๋ถ ๊ณต์ฉ ์ฌ์ฉ์ ์ํด ๋ด๋ณด๋ด์ง๋๋ค. iife์ ์ฌ์ฉ์ ์ฐ๋ฆฌ ํ๋ก๊ทธ๋จ์ด ์ผ๋ฐ์ ์ผ๋ก "์ฑ๊ธ ํค"์ด๋ผ๊ณ ํ๋ ์ค์ ๋ชจ๋์ ๋จ์ผ ์ธ์คํด์ค๋ง ํ์ํจ์ ์๋ฏธํฉ๋๋ค.
Module Factory (Multiple Instances)
// 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
Node CommonJS Modules
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;
}
// defining a new object for the API
module.exports = {
// ..exports..
};
์ด๊ฒ๋ณด๋ค๋ ์์ ๋ณต์ฌ๋ฅผ ์ํํ๋ ์๋๋ก ์ฌ์ฉํฉ์๋ค.
Object.assign(module.exports,{
// .. exports ..
});
์ ๊ทผ์ ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
var getName = require("/path/to/student.js").getName;
// or alternately:
var { getName } = require("/path/to/student.js");
Node์์ require๋ ์ ๋๊ฒฝ๋ก๋ฅผ ์ฐพ์ ๋ค node_modules์์ ์ฐพ์ต๋๋ค.
Modern ES Modules (ESM)
export { 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;
}
export function getName(studentID) {
// ..
}
export default function getName(studentID) {
// ..
}
๋ค์์ ์ผ๋ฐ์ ์ผ๋ก ๋ถ๋ฌ์ฌ ๋ ์ฐ๋ ์ฝ๋ ์ ๋๋ค.
import { getName } from "/path/to/students.js";
getName(73); // Suzy
import { getName as getStudentName } from "/path/to/students.js";
getStudentName(73); // Suzy
๋ง์ฝ default export๋ฅผ ์ฌ์ฉํ๋ค๋ฉด ๋ค์๊ณผ ๊ฐ์ด ๋ถ๋ฌ์ฌ ์ ์์ต๋๋ค.
import getName from "/path/to/students.js";
getName(73); // Suzy