There are two characteristics implicit in this definition of modules and both of these characteristics need to be present for you to be using the module pattern.
- The first characteristic is that there has to be an outer enclosing function that runs at least once.
- There needs to be at least one internal function that returns back in the public API that has closure over the internal state.
Benefits:
- Encapsulation (hiding) of things we don't want to expose
- organizing your code
Downsides:
- Testability (how are you going to do function testing?)
var foo = {
o: { bar: 'bar' },
bar() {
console.log(this.o.bar);
}
};
foo.bar(); // "bar"
So everyone has access to foo.o
.
var foo = (function() {
var o = { bar: 'bar' };
return {
bar: function() {
console.log(o.bar);
}
};
})();
foo.bar(); // "bar"
In this way o
cannot be accessed outside of the function.
With this way we gain the benefit that we can access our "public API" internally.
var foo = (function() {
var publicAPI = {
bar: function() {
publicAPI.baz();
},
baz: function() {
console.log(o);
}
};
var o = 'baz';
return publicAPI;
})();
foo.bar(); // "baz"
Again o
cannot be accessed outside of the function.
define('foo', function() {
var o = { bar: 'bar' };
return {
bar: function() {
console.log(o.bar);
}
};
});
foo.js
var o = { bar: 'bar' };
export function bar() {
return o.bar;
}
import { bar } from 'foo.js';
bar(); // "bar"
import * as foo from 'foo.js';
foo.bar(); //"bar"