It took me a long time to understand this pattern at first, and I think it is mostly because of the way that it is written:
(function(root, factory) {
// Export MyModule depending on the environment
if (typeof define === "function" && define.amd) {
define("MyModule", [], factory);
} else {
root.MyModule = factory();
}
}(this, function() {
return {
// Module definition
};
}));
Isn't that the exact same thing as this?
(function(root) {
var factory = function() {
return {
// Module definition
};
};
// Export MyModule depending on the environment
if (typeof define === "function" && define.amd) {
define("MyModule", [], factory);
} else {
root.MyModule = factory();
}
}(this));
There is a var statement now, but I find this much easier to read. Am I missing something here? Is there a good reason to use the first approach?
Isn't that the exact same thing as this?
Not exactly - those root
and factory
variables are now in the scope of the module definition, it is one closure level deeper. And this has the grave disadvantage that factory
cannot (trivially) be garbage-collected any more, while in the first pattern it was really anonymous.
I find this much easier to read
I disagree. AMD and UMD resolve around a single "define" wrapper that is called with a factory - where the contents of the factory function are the interesting ones (the "main" content of the file) and the definition call is nothing more but a header. This becomes especially obvious when the header is minified and takes only a single line.
In contrast, in the proposed alternative the module is hidden somewhere deep in that IEFE - it even needs to be indented one more level than normally.