DEV Community

Cover image for Objective JS with IIFE
Henrick Tissink
Henrick Tissink

Posted on • Updated on

Objective JS with IIFE

JavaScript is a Multi-Flavored Beast

As a C# developer; an OOP developer; a developer who likes encapsulation and re-usability, Vanilla JavaScript, and all its wonderful uses scared me - until I stumbled upon the simple concept of an IIFE - Immediately Invoked Function Expression.

Some OOP in the JavaScript Sauce

sauce

There are so many ways to do things in JavaScript, it can be a little overwhelming for an OOP developer. Where are the classes? Where is the encapsulation? It's all so functional - and so very against the nature of OOP.

IIFEs may not be good (or bad) but they give a way to bring order to Vanilla JavaScript, without having to use any frameworks or clever packages. They're relatively simple, and easy to understand - as will be seen in the example. IIFEs are by no means the correct way to do this - just simply a way that brings a little bit of order to the creative chaos.

The Simplest Example

// Reusable modules
var someModule = (function() {
  // private "members" - Here we use closure to ensure that only the object being returned can access these members
  var privateVar = 'A private variable';

  function privateMethod() {
    console.log('This is a private method')
  };

  return {
    // Public variables
    PublicVar: 'A public variable',

    // Public methods
    publicMethod() {
      console.log('A public function');
    },
    usingPrivateVariables() {
      console.log('Using a private variable')
      console.log(privateVar);
    },
    usingPrivateMethod() {
      console.log('Calling a private method')
      privateMethod();
    }
  };

}());
Enter fullscreen mode Exit fullscreen mode

Does it work as Advertised?

someModule.publicMethod();
// Output: 'A public function'

someModule.usingPrivateVariables();
// Output: 'using a private variable'
// Output: 'A private variable'

someModule.usingPrivateMethod();
// Output: 'Calling a private method'
// Output: 'This is a private method'

console.log(someModule.PublicVar)
// Output: 'A public variable'

console.log(someModule.privateVar)
// Output: undefined
// It's private :)

console.log(someModule.privateMethod())
// Output: someModule.privateMethod is not a function
// It's private too!
Enter fullscreen mode Exit fullscreen mode

IIFE or Iffy?

interesting

With modern frameworks, IIFEs are a little redundant (or Iffy) - the likes of Angular, Vue, and React (to name a few) with their structured way of doing things makes the concept a little obsolete.

However I've found IIFEs to be wildly useful in older projects - like ASP.NET MVC, especially with JQuery added to the mix. You can abstract out the actual JQuery calls to separate modules; create private and public variables and functions, and do this all in a modular way. IIFEs add a level of re-usability to code in a way that makes sense to my OOP oriented mind.

They've helped me tremendously in untangling otherwise very complex blotches of JavaScript - and I hope they may help some other poor souls struggling with similar issues.

Discussion (6)

Collapse
zoedreams profile image
☮️✝️☪️🕉☸️✡️☯️ • Edited on

check this out. i wrote this a few years back. nice to see someone else come to the same solution. great work!

class Clazz {
  constructor() {
    var _level = 1

    function _private(x) {
      return _level * x;
    }
    return {
      level: _level,
      public: this.private,
      public2: function(x) {
        return _private(x);
      },
      public3: function(x) {
        return _private(x) * this.public(x);
      },
    };
  }

  private(x) {
    return x * x;
  }
}

var clazz = new Clazz();

console.log(clazz._level); //undefined
console.log(clazz._private); // undefined
console.log(clazz.level); // 1
console.log(clazz.public(1)); //1
console.log(clazz.public2(2)); //2
console.log(clazz.public3(3)); //27
console.log(clazz.private(0)); //error

my answer on stackoverflow stackoverflow.com/a/46707381/334927

***please note that not declaring the namespace with class or a symbol reference, the type checking will be reverted to string and shallow. This means that deep typeof or === object compares will most likely will false positives.such as isBool: true !== "true" || true || 0

Collapse
256hz profile image
Abe Dolinger

I don't understand, what makes this more natural than using Javascript class sugar? Or are you limited to pre-ES6 javascript?

Collapse
htissink profile image
Henrick Tissink Author

Exactly this - the technique becomes really useful when you're limited to older versions of JS. To add to this, how would you declare private members within the class sugar?

Collapse
256hz profile image
Abe Dolinger

Makes sense! I didn't see it laid out in the post that this was specifically for older JS. Typescript gives you private and public methods at design time (i.e., private methods become public on compile, but won't compile if used improperly). Doesn't help if you're in a legacy codebase, but at least the possibility has existed for a while!

Collapse
clsource profile image
Camilo

Thanks. I have been using this technique but didn't know the technical name :). Also objective js reminded me of objective-j github.com/cappuccino/objjc :)

Collapse
htissink profile image
Henrick Tissink Author

Oh wow! I actually kinda loved objective-c (I know I'm weird lol). Will definitely check this out :) thanks so much for sharing.