Difference between revisions of "An Argument Against Requiring IIFEs"

From Yanfly.moe Wiki
Jump to navigation Jump to search
(The Common Arguments In Favor of IIFE's)
(Real Applications of IIFE's)
Line 79: Line 79:
  
 
# Isolation of variables, making them private and unchangeable
 
# Isolation of variables, making them private and unchangeable
# Running a One-Time Planned Function
 
 
# Usage of placing functions, content extensions, and/or snippets loaded from cross-net providers (such as analytics, ads, widgets, etc.)
 
# Usage of placing functions, content extensions, and/or snippets loaded from cross-net providers (such as analytics, ads, widgets, etc.)
 +
# Running an unnamed one-time planned function
  
 +
Now, if you're planning on arguing from these perspectives, allow me to counter them, too.
 +
Yes, I am arguing with myself here.
 +
 +
 +
 +
=== 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.
 +
 +
<pre>
 +
const createId = (function () {
 +
  let id = 0;
 +
  return function () {
 +
    id++;
 +
    return id;
 +
  }
 +
})();
 +
 +
createId(); // 1;
 +
createId(); // 2;
 +
id = 10000; // throws an exception because id is not in scope
 +
</pre>
 +
 +
Makes sense?
 +
 +
Usage of 'const' to declare a variable in the global namespace prevents it from being changed at all, too.
 +
 +
<pre>
 +
const x = 100;
 +
x = 200; // throws an error because 'x' was already declared by const and prevents it from changing
 +
</pre>
  
 
== End of File ==
 
== End of File ==
  
 
|}
 
|}

Revision as of 22:07, 7 November 2021

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


Yanfly.png This is an article written by Yanfly.

Introduction

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:

(function () {
    ...
})();

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 need to be wrapped around in an IIFE. I personally don't believe that. In fact, doing such a thing will often lead to problems later down the road especially if a plugin library gets bigger and bigger.


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. Very few experienced 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, while using 
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. Usage of placing functions, content extensions, and/or snippets loaded from cross-net providers (such as analytics, ads, widgets, etc.)
  3. Running an unnamed one-time planned function

Now, if you're planning on arguing from these perspectives, allow me to counter them, too. Yes, I am arguing with myself here.


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.

const createId = (function () {
  let id = 0;
  return function () {
    id++;
    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

End of File