- Joined
- Mar 24, 2012
- Messages
- 15
- Reaction score
- 6
- First Language
- English
- Primarily Uses
- N/A
Quoting the Basics section of the Plugin Specifications page of the documentation:
This appears to be a requirement that only IIFEs may appear at the top level of a plugin source file. And there's a good reason for such a requirement. The alternative way to limit the scope of names would be to enclose their declarations in braces, but Javascript has a feature called variable hoisting that weakens the protection against accidentally polluting the containing namespace that braces would otherwise provide:
If you're using braces and you want to avoid polluting the containing namespace, you have to be careful to declare your variables with "let" instead of "var":
IIFEs don't have any such weakness - you can declare a variable inside an IIFE without being careful about which keyword you declare it with, and there's no risk of polluting the IIFE's containing namespace:
But when I look at the code of some example plug-ins, I see declarations outside of IIFEs at the top level of the source file. This even happens in one of the official plug-ins MadeWithMv.js - the first few non-comment lines are:
and they're not in an IIFE, so they add the name Liquidize to the containing namespace.
So it looks like "Only IIFEs allowed at top level of plug-in source" isn't a hard rule - it's just a guideline. Is this the case? Or does the engine have some way of enforcing it that'll come back to bite me later?
In order to limit the scope of variables in plugin scripts, they will all be enclosed in immediate functions.
This appears to be a requirement that only IIFEs may appear at the top level of a plugin source file. And there's a good reason for such a requirement. The alternative way to limit the scope of names would be to enclose their declarations in braces, but Javascript has a feature called variable hoisting that weakens the protection against accidentally polluting the containing namespace that braces would otherwise provide:
JavaScript:
{
// MyVariable is declared in these braces, so this is the scope it's in, right?
var MyVariable = 0;
}
// Ha ha, surprise! MyVariable was hoisted into this scope!
MyVariable = 1;
If you're using braces and you want to avoid polluting the containing namespace, you have to be careful to declare your variables with "let" instead of "var":
JavaScript:
{
// MyVariable is declared in these braces, so this is the scope it's in, right?
let MyVariable = 0;
}
// Yes, this time it is. Variables declared with "let" aren't hoisted and the following line is an error.
MyVariable = 1;
IIFEs don't have any such weakness - you can declare a variable inside an IIFE without being careful about which keyword you declare it with, and there's no risk of polluting the IIFE's containing namespace:
JavaScript:
(() => {
{
// MyVariable is declared here ...
var MyVariable = 0;
}
// ... and it gets hoisted to here ...
MyVariable = 1;
})();
// ... but no higher, because variables are not hoisted out of IIFEs - this line is an error.
MyVariable = 2;
But when I look at the code of some example plug-ins, I see declarations outside of IIFEs at the top level of the source file. This even happens in one of the official plug-ins MadeWithMv.js - the first few non-comment lines are:
JavaScript:
var Liquidize = Liquidize || {};
Liquidize.MadeWithMV = {};
Liquidize.MadeWithMV.Parameters = PluginManager.parameters('MadeWithMv');
Liquidize.MadeWithMV.ShowMV = JSON.parse(Liquidize.MadeWithMV.Parameters["Show Made With MV"]);
Liquidize.MadeWithMV.MVImage = String(Liquidize.MadeWithMV.Parameters["Made with MV Image"]);
Liquidize.MadeWithMV.ShowCustom = JSON.parse(Liquidize.MadeWithMV.Parameters["Show Custom Splash"]);
Liquidize.MadeWithMV.CustomImage = String(Liquidize.MadeWithMV.Parameters["Custom Image"]);
Liquidize.MadeWithMV.FadeOutTime = Number(Liquidize.MadeWithMV.Parameters["Fade Out Time"]) || 120;
Liquidize.MadeWithMV.FadeInTime = Number(Liquidize.MadeWithMV.Parameters["Fade In Time"]) || 120;
Liquidize.MadeWithMV.WaitTime = Number(Liquidize.MadeWithMV.Parameters["Wait Time"]) || 160;
and they're not in an IIFE, so they add the name Liquidize to the containing namespace.
So it looks like "Only IIFEs allowed at top level of plug-in source" isn't a hard rule - it's just a guideline. Is this the case? Or does the engine have some way of enforcing it that'll come back to bite me later?