In a simple UMD setup like the following, where/how are root
and factory
defined?
(function (root, factory) {
// environment detection here
console.log(root);
console.log(factory);
}(this, function (b) {
// module definition here
}));
I'm arriving late to the UMD party, so please forgive me if this is a silly question... but if I run the above code, I see root
returns the window object, and factory
returns a function. So is the first argument (in this case, root) always defined as the window object? What about the second? Are they implemented the same cross browsers? I'm searching high and low for a spec or reference to back this up and can't find one... there are lots of blog posts about the wonders of UMD, but I can't find any explanation of how this magically works.
Does anybody have a simple explanation for how or why this works?
This is an IIFE (immediately-invoked function expression), which is nicely explained here.
To put it simply you are creating a function that is only called once and you are passing to it two arguments, this
and function(b)
. These two arguments are named root
and factory
inside the IIFE body.
The benefit is that the body of IIFE works in isolation, in a "private scope". Variable names outside of it have no effect and you have no conflict problems.
Now, back to your question, you are passing this
as an argument. This is the global object. In a browser it is window
and in Node it is global
. In both cases in the IIFE you are referring to it as root
and in your module as b
. What ever you call it, another advantage is that your minifier can pick it up and translate it to c
or something else without breaking your code. This is in contrast with a normal situation, where window
or document
or any module names can't be minified.
You are also passing a function, which is named factory. This is your module. Without AMD or CommonJS, you would usually do:
(function (root, factory) {
root.myModuleName = factory(root);
}(this, function (b) {
// module definition here
}));
This will create your module and attach it to the global object, so that you can use it. With only one argument in factory method, you normally need to pass the global object. You can also use more arguments to pass any module dependencies:
(function (root, c, factory) {
root.myModuleName = factory(root, c);
}(this, jQuery, function (b, $) {
// module definition here
// You refer to jQuery as $ without having to call noConflict
}));
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With