An Argument Against Requiring IIFEs

From Wiki
Jump to navigation Jump to search

Welcome to the wiki! This is where you can find resources from, Æ,
VisuStella, Caz Wolf, Fallen Angel Olivia, Atelier Irina, and other affiliated content creators.

Yanfly.png This is an article written by Yanfly.


Nah IIFE.jpg

This is a programming article, so if you don't understand JavaScript, don't care about JavaScript, or don't care about Immediately-Invoked Function Expressions (IIFE's), this article will probably mean nothing to you.

Now that that's out of the way, let's make sure we're all on the same page here. An Immediately-Invoked Function Expressions (IIFE) is the following:

(() => {

It's a private scope that's created within the code that will run immediately upon its code being read. This has applications, yes, and from personal experience, there are times where its useful, too.

However, there's been a trend in the RPG Maker community, especially amongst plugin developers, that argue that entire plugins are required and need to be wrapped around in an IIFE.

I personally don't believe that they are required a single bit.

And as a person who used to get a lot of $#!% back in the day for not using them, here is why.

The Common Arguments In Favor of IIFE's

Here are the things I've seen people argue in favor of IIFE's:

  1. Not polluting the global namespace
  2. Keeping code private and unreadable from NodeJS's dev tools

Not Polluting the Global Name Space

In regards to the first: Not polluting the global namespace, uh, I'm not sure about you, but that's almost never gonna be a major issue especially when programmers become more experienced and responsible. Very few experienced and responsible programmers actually declare commonly used variable names inside the global namespace unless they have a reason to do it. The majority of programmers already declare their own global namespace object and place their declared variables inside of that instead.

// This is what "polluting the namespace" looks like:
var x = Window_Base.prototype.initialize;
var y = Window_Base.prototype.lineHeight;

// In the above example, uses of 'x' and 'y' can be called from the global namespace.
// Since 'x' and 'y' are highly common variable names, it's likely to be overwritten.
// This can lead to any code that utilize 'x' and 'y' as called functions to not work.

// This what experienced programmers do:
var ProgrammerName = {};
ProgrammerName.Window_Base_initialize = Window_Base.prototype.initialize;
ProgrammerName.Window_Base_lineHeight = Window_Base.prototype.lineHeight;

// Only 'ProgrammerName' appears in the global namespace and it appears as an object.
// The stored functions can be called from 'ProgrammerName.Window_Base_initialize' and
// the like with a low likelihood of being overwritten.

Keeping code private and unreadable from NodeJS's dev tools

In regards to the second point: Keeping code private and unreadable from NodeJS's dev tools, this is meaningless unless you have the code obscured from legibility, too. Especially if the "user", whether it is the game developer or the player, can simply open up the plugin's JS file and read what's there.

While sure, they won't be able to run it directly from the dev tools console, it doesn't change the fact the user can still just copy the contents of a specific function, declare it publicly in the dev tools console (and thus, the global name space), and proceeding to invoke it on demand. See below:

IIFE Example 1.png

Real Applications of IIFE's

Now, let's talk about the real applications of IIFE's. These are arguments that I seldom see mentioned in the RPG Maker community, but I don't want people saying I'm cherrypicking bad examples. Instead, I'll provide legitimate cases for IIFEs:

  1. Isolation of variables, making them private and unchangeable
  2. Running an unnamed one-time planned function
  3. Usage of placing external web functions, content extensions, and/or snippets loaded from cross-net providers (such as analytics, ads, widgets, etc.)

Now, if you're planning on arguing from these perspectives, allow me to elaborate on them, too.

Isolation of variables, making them private and unchangeable

This is the primary and most viable reason for most programmers out there. Programmers are picky and territorial creatures. They don't like it when you touch their code. They especially don't like it when you touch their variables. And before, in the past, programmers would isolate and privatize their variables via IIFE's.

However, nowadays, that's not needed anymore. Why not? Because of the creation of the 'let' and 'const' variable declarations. On top of that, modules are also automatically isolated within their own functions. 'let' and 'const' allowed the restrictions to go to even smaller scopes, such as their own bracketed conditional blocks.

Below is an actual example of proper isolation in play:

const createId = (() => {
    let id = 0;
    return () => {
        return id;

createId(); // 1;
createId(); // 2;
id = 10000; // throws an exception because id is not in scope

Makes sense?

Usage of 'const' to declare a variable in the global namespace prevents it from being changed at all, too.

const x = 100;
x = 200; // throws an error because 'x' was already declared by 'const' and prevents it from changing

Usage of 'let' to declare a variable in the global namespace allows it to be changed, but prevents it from being redeclared.

let x = 100;
x = 200;
console.log(x); // 200

// Variable 'x' can have its variable changed.

var x = 500; // throws an error because 'x' was already declared by 'let'

As you can see, isolating and privatization of variables makes usage of IIFE's for that purpose moot.

Running an unnamed one-time planned function

It makes sense, if you want to make an unnamed one-time planned function to run and then immediately be gone forever, then yeah, use an IIFE for it. In my opinion, you can never tell when you would want to run a function more than once so it's best to keep them publicly available. However, if you do have a case for it, then yeah, I will concede that's a legitimate reason to use the IIFE. In fact, VisuStella MZ does use IIFE's for those reasons, albiet extremely rare.

External web functions, Content extensions, and/or Snippets

The majority of these cases aren't used for games that are created by RPG Maker. And in the event there are uses for them, there's little need to make a counter point. This is probably the only real legitimate case for the usage of IIFE's for RPG Maker games, even if extraordinary rare.

Incorrect Usage

Plugin-Wide IIFE Wrappers

However, if this argument is to be used to explain wrapping IIFE's around entire plugins, then that makes no sense.

(() => {

const ProgrammerName_Window_ActorCommand_addAttackCommand = Window_ActorCommand.prototype.addAttackCommand;
Window_ActorCommand.prototype.addAttackCommand = function() {
    var NEO_ATTACK_ID = 42;
    if (this._actor.isStateAffected(NEO_ATTACK_ID)) {
    } else {;


I see plugins using the IIFE's like above and see nothing coming out of it. If you remove the IIFE wrappers, you get the same results.

Instead, it's just privately declaring monkey patched variables that are being used for a public function. You get almost the same exact results as the following without any IIFE's:

const ProgrammerName_Window_ActorCommand_addAttackCommand = Window_ActorCommand.prototype.addAttackCommand;
Window_ActorCommand.prototype.addAttackCommand = function() {
    var NEO_ATTACK_ID = 42;
    if (this._actor.isStateAffected(NEO_ATTACK_ID)) {
    } else {;

The difference here is, 'ProgrammerName_Window_ActorCommand_addAttackCommand' can be called from a public scope, which is better by far.

Why Plugin-Wide IIFE's are a Problem

Making monkey patches in a private scope create tons of problems. Let's assume the following are two different plugins:

// Plugin #1
(() => {

const ProgrammerName_Window_ActorCommand_addAttackCommand = Window_ActorCommand.prototype.addAttackCommand;
Window_ActorCommand.prototype.addAttackCommand = function() {
    var NEO_ATTACK_ID = 42;
    if (this._actor.isStateAffected(NEO_ATTACK_ID)) {
    } else {;

// Plugin #2
(() => {

const ProgrammerName_Window_ActorCommand_addNeoAttackCommand = Window_ActorCommand.prototype.addAttackCommand;
Window_ActorCommand.prototype.addAttackCommand = function() {
    var NEO_ATTACK_ID = 42;
    var SEAL_NEO_ATTACK_ID = 43;

    if (this._actor.isStateAffected(NEO_ATTACK_ID) && this._actor.isStateAffected(SEAL_NEO_ATTACK_ID)) {;
    } else {;


In the above case, as the two IIFE's created two private scopes, 'ProgrammerName_Window_ActorCommand_addAttackCommand' cannot be used to add the original 'Attack' command anymore that was created by the first instance. While this seems a bit unusual, there are indeed times where you want to be able to call the original functions that are untouched by any modifying code and adding those to a private scope will prevent that. Now if this is the intent of the creator of the said function, then there's really not much else you can do.

Classes Stuck Inside IIFE's

To go past that, there are also times I've seen where new classes are entirely engulfed inside of the IIFE. This makes it not only impossible to call the class from a public scope, but you can't even make extensions or monkey to patches from a scope different from the own individual private scope.

IIFE 02.png

The above was using a class a made from TinyGetInfoWndMZ, a plugin that came with RPG Maker MZ's DLC. However, because the class is found inside the IIFE, it is completely inaccessible from the public scope. If I wanted to make my own special popup using this class or to make changes to it, it's not possible unless I were to edit the actual plugin itself. Or, as demonstrated before, just redeclaring the contents of the class in a public scope and then reusing it there.

Now, this may be the actual intent of the creator. If they don't want anyone using their functions or classes from the public scope, then yes, throw the contents into the IIFE wrapper. Assuming that is the case, it's fine where it is, even if there's nothing that prevents the redeclaration of the said class in a public scope.

However, if it is not, then it's better to keep things outside of IIFE wrappers to ensure global accessibility.

Programmers Admitting They're Lazy

I also see a trend nowadays with the RPG Maker community's programmers justifying IIFE's because they're "lazy" and don't want to declare their own namespace objects to store everything.

Okay, that's cool. You do you. I'm not going to harp on your programming practices because that's not a thing that I do. (and in case you're wondering, this article is just made as a counterargument towards the required usage of IIFE's, not pushing my own programming practices on anyone else)

Just keep in mind that if your whole reason to require usage of IIFE's is to allow you to be lazy, you're not going to be doing a very good job of convincing people on why IIFE's are required to wrap a plugin.


Nah IIFE.jpg

There's little reason to use IIFE's anymore. The only reasons I can think of are the extremely rare cases where a piece of code is to run once and only once and to be forgotten for the remainder of the gaming session or if the code is coming from a privatized widget, ad, or application. Also, if a programmer doesn't want people accessing their code and classes through the public scope, then sure, throw it into an IIFE.

Otherwise, I say don't let other programmers peer pressure you into using them for silly reasons like not polluting the global namespace or keeping code private (while the rest of the plugin is legible).

All the very same, I also advise you to consider the actual usages of IIFE's or not using IIFE's for yourself, not just simply because "Yanfly said it's okay to not use IIFE's".

Always seek the answers on your own and come up with your own conclusions. The whole purpose of this article is for programmers in the RPG Maker community to see an alternative stance in regards to IIFE's not to steer them completely away from it. If they have reasons to use IIFE's that aren't listed here, all the more kudos to them. However, if you are being fed those reasons, make sure you can distinguish if they're applicable to you as a responsible programmer.

End of File