In general, no; the IIFE pattern is seldom useful for wrapping a whole userscript (see edge cases below). That's a throwback to many years ago when some engines (briefly) did not wrap scripts by default.
In fact, if you include the obsolete @unwrap
directive, the script engines will all now ignore it.
Here are some reasons to use the IIFE pattern:
- It was the only way to enforce
strict
mode in old versions of Violentmonkey (2018 or earlier) for the whole script.
- It can squelch a harmless
Parsing error: 'return' outside of function
warning if you use BOTH: (1) A script-wide return
and (2) an external LINTer.
Some old Greasemonkey versions would also warn about this, while still working perfectly.
- (I thought there was a 3rd edge case. But got interrupted and can't remember what it was.)
Consider this test script:
// ==UserScript==
// @name _Scope and Strict-Mode Demo script
// @match https://stackoverflow.com/*
// @unwrap
// @grant none
// ==/UserScript==
/* eslint-disable no-multi-spaces, curly */
'use strict';
if (location.pathname.includes("/users/") ) {
console.log ("Terminating script early.");
return; // In external LINTers, this will cause a harmless warning.
}
var cantSeeMeInConsole = "neener neener";
window.canSomestimesSeeMe = "Howdy";
console.log (`In Strict mode: ${bInStrictMode() }; \`cantSeeMeInConsole\`: ${cantSeeMeInConsole}`);
function bInStrictMode () {
var inStrict = false;
var dummyObj = {};
Object.defineProperty (dummyObj, 'foo', {value: "bar", writable: false } );
try { dummyObj.foo = "fee"; }
catch (e) { inStrict = true; }
return inStrict;
}
- Run on Firefox and Chrome.
- Safari and Opera should give same results.
- Microsoft Edge probably gives same results. (But I don't care much if it doesn't.)
- Run using Tampermonkey, Violentmonkey, and Greasemonkey 4.
Script scoping:
In all cases, the userscript is scoped/wrapped. The page can't see code, nor variables like cantSeeMeInConsole
.
Beware that script page conflicts can still occur in @grant none
mode.
Script sandboxing:
Additional isolations apply, depending on: (a) the userscript engine, (b) the browser, and (c) the @grant
mode.
For example, using Greasemonkey, or changing the grant mode kills the page's ability to see canSomestimesSeeMe
.
Strict mode:
- Placing
'use strict';
up top like that switches the whole userscript into strict mode.
- Additionally, in Tampermonkey's advanced options, you can set "strict mode" to [Default/Always/Disabled] for all scripts.
In a related note, if the script does not use @run-at
settings, there is no point in using $(document).ready()
or its shorthand.
use strict
and another doesn't. Also,var
s on the top level inside a userscript don't look to be assigned to the window regardless, even with@grant none
, so it doesn't look to avoid globals either. I see no benefit to the IIFE, but I'm not 100% sure – Grackleuse strict
inside an IIFE will help avoid the linter warning in the IDE you're writing the code in, if you happen to be using an IDE with a linter. (and the explicitly stateduse strict
helps tell the IDE that the code below should be interpreted as being in strict mode.) But that's very tenuous. – GrackleAlways
. – Ablation