https://www.freecodecamp.org/news/javascript-modules-a-beginner-s-guide-783f7d7a5fcc/
JavaScript Modules: A Beginner’s Guide
by Preethi Kasireddy JavaScript Modules: A Beginner’s Guide Source: https://www.flickr.com/photos/qubodup/16258492451If you’re a newcomer to JavaScript, jargon like “module bundlers vs. module loaders,” “Webpack vs. Browserify” and “AMD vs. CommonJS” can q
www.freecodecamp.org
작곡가는 곡의 파트를 나누고, 작가는 글의 챕터를 나눈다. 프로그래머는 프로그램의 코드를 모듈로 나눈다. 모듈( Module )이 뭔가 ?
간단히 생각해서 코드같은 언어의 뭉치? 같은 개념이라고 생각 할 수 있다.
물론 좋은 모듈은 특정 목적을 위해 기능적으로 구분된 뭉치라고 볼 수 있다.
이같은 모듈을 프로그램에 통합 시키는 방법이 여러가지 있다.
- Anonymous closure
(function () {
// We keep these variables private inside this closure scope
var myGrades = [93, 95, 88, 0, 55, 91];
var average = function() {
var total = myGrades.reduce(function(accumulator, item) {
return accumulator + item}, 0);
return 'Your average grade is ' + total / myGrades.length + '.';
}
var failing = function(){
var failingGrades = myGrades.filter(function(item) {
return item < 70;});
return 'You failed ' + failingGrades.length + ' times.';
}
console.log(failing());
}()); // ‘You failed 2 times.’
위의 예제에서는 average, failing 변수에 익명의 클로저 함수를 할당하고 전체를 IIFE( Immediately-Invoked Function Expressions )로 모듈을 만들어 사용하였다.
이러한 방식의 장점은 함수 내부의 로컬 변수에 접근을 하면서 동시에 글로벌 변수들의 namespace를 해치지 않는다는 점이다.
- Global import
(function ( globalVariable ) {
// Keep this variables private inside this closure scope
var privateFunction = function() {
console.log('Shhhh, this is private!');
}
// Expose the below methods via the globalVariable interface while
// hiding the implementation of the method within the
// function() block
globalVariable.each = function(collection, iterator) {
if (Array.isArray(collection)) {
for (var i = 0; i < collection.length; i++) {
iterator(collection[i], i, collection);
}
} else {
for (var key in collection) {
iterator(collection[key], key, collection);
}
}
};
globalVariable.filter = function(collection, test) {
var filtered = [];
globalVariable.each(collection, function(item) {
if (test(item)) {
filtered.push(item);
}
});
return filtered;
};
globalVariable.map = function(collection, iterator) {
var mapped = [];
globalUtils.each(collection, function(value, key, collection) {
mapped.push(iterator(value));
});
return mapped;
};
globalVariable.reduce = function(collection, iterator, accumulator) {
var startingValueMissing = accumulator === undefined;
globalVariable.each(collection, function(item) {
if(startingValueMissing) {
accumulator = item;
startingValueMissing = false;
} else {
accumulator = iterator(accumulator, item);
}
});
return accumulator;
};
}( globalVariable ));
위의 글로벌 임폴트 예제가 좀 길긴 한데 이러한 방식은 클로저를 만드는 방법과 비슷하다. 받은 파라미터가 글로벌 변수인 점을 빼고.
이렇게 하는 이유는 그냥 코드를 읽기 쉽게 하려고 한단다.
- Object interface
var myGradesCalculate = (function () {
// Keep this variable private inside this closure scope
var myGrades = [93, 95, 88, 0, 55, 91];
// Expose these functions via an interface while hiding
// the implementation of the module within the function() block
return {
average: function() {
var total = myGrades.reduce(function(accumulator, item) {
return accumulator + item;
}, 0);
return'Your average grade is ' + total / myGrades.length + '.';
},
failing: function() {
var failingGrades = myGrades.filter(function(item) {
return item < 70;
});
return 'You failed ' + failingGrades.length + ' times.';
}
}
})();
myGradesCalculate.failing(); // 'You failed 2 times.'
myGradesCalculate.average(); // 'Your average grade is 70.33333333333333.'
self-contained object interface(이게 한국말로 뭔지 모르겠다)를 사용해서 모듈을 만든 예제이다.
이러한 방식의 모듈의 장점은 어떤 변수나 메소드를 private할지 혹은 expose할지 결정할 수 있다는 점이다.
함수안에 return 안에 있는 것들이 노출을 시키려고 의도를 하였고, 나머지 부분(myGrades)를 프라이빗으로 감추었다.