Following are two ways to define BW.Timer. Can someone tell me what the difference is? I am not certain the first is even valid, but if it is valid, what is different about using the myfunc=(function(){}())
syntax?
BW.Timer = (function () {
return {
Add: function (o) {
alert(o);
},
Remove: function (o) {
alert(o);
}
};
} ());
And...
BW.Timer = function () {
return {
Add: function (o) {
alert(o);
},
Remove: function (o) {
alert(o);
}
};
};
The first is the return-value of the immediately-invoked function. The second is a function. It essentially comes down to what the difference is between these:
var f = (function() { return 0; })();
var f = function() { return 0; };
Since the first function is called immediately, the value of 0 is given to the variable f
. The first f
is not a function. However, the second f
we must call in order to get the value:
f(); // 0
It follows that in your example, the first BW.Timer
is the object literal itself and the second is a function returning an object literal. You must call the function in order to get to the object:
BW.Timer().Add(x);
You might ask yourself why one would use a syntax like a = (function() { return {}; })()
instead of a = {}
, but there's a good reason. An IIFE (Immeditately-Invoked Function Expression), unlike a regular function allows the emulation of static variables (variables that maintain their value through a single instance). For example:
var module = (function() {
var x = 0;
return { get: function() { return x },
set: function(n) { x = n }
};
})();
The above a text-book example of the Module Pattern. Since the function is called right away, the variable x
is instantiated and the return value (the object) is given to module
. There's no way we can get to x
other than by using the get
and set
methods provided for us. Therefore, x
is static, meaning its variable won't be overridden each time you use module
.
module.set(5);
module.get(); // 5
On the other hand, let's see an example where module
is declared as a function instead:
// assume module was made as a function
module().set(5);
module().get(); // 0
When we call module()
the x
variable is overridden each time. So we're effectively using different instances of module
and x
each time we call module
.
The difference is rather large.
In the first case, BW.Timer
is executed when it is first encountered, and that is the static version assigned to BW.Timer
. In that instance, BW.Timer.Add(1)
may be used. Each call to BW.Timer
will be the same object.
In the second case, BW.Timer
is not executed when first encountered, and instead is a function referece which must be invoked BW.Timer()
. For Add
to be used, this must be the case BW.Timer().Add(1)
. Also, you can issue var timer = new BM.Timer();
. Each instance of BW.Timer()
will be unique here.
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