1

Upon exploring a JavaScript library I was interested in, I came across this strange IIFE. I cannot find any information on this pattern and am lead to believe its custom tailored for this use case. I can't quite wrap my head around what is happening here, but intuition has me thinking it may be similar to the Singleton pattern. Here is a shortened example showing off what I believe to be the core of the code:

var Ctor = (function () {

  function dostuff(_this, args...){}//only used within this iife

  var Ctor = function (args...) {
    if (!this || this === window) {
      return new Ctor(args...);
    }
    dostuff(this, args...);
    return this;
  };
  return Ctor;
})();

Note, I changed the names of the functions to reflect what I believe they're responsible for, but my assumptions could be wrong and I could be further making the code unintelligible. The source I linked to is about 60 lines long so I'd suggest giving that a look for hints if this version makes no sense. (Changes I made are Ctor <=> Bind, dostuff <=> extend)

As for my questions:

  1. What is this design pattern? (if applicable)
  2. What is the inspiration for using a pattern like this?
  3. What are some other real world applications for this pattern?
  4. Is there a more standard/readable way of writing this that produces the same functionality?
Siracle
  • 332
  • 2
  • 10
  • `var Ctor = (function () { return …; })();` is just the standard IIFE pattern, nothing special about it. – Bergi Dec 18 '18 at 07:41
  • Regarding `if (!this || this === window) { return new Ctor(args...); }`, see [When should I automatically create an object even if `new` is forgotten?](https://stackoverflow.com/q/20859985/1048572) Notice that it's pretty outdated as of ES6 (you should just throw an exception), but it increases usability. – Bergi Dec 18 '18 at 07:44

1 Answers1

0

After spending some time trying to figure out the exact nature of the code, I discovered its practical use. From here, Googling the question became much easier, and I immediately found This Post. Here are the answers I've come up with to my questions. Feel free to correct any of this or add to the discussion!

  1. It is a creation pattern that abstracts away the need to use "new" when instantiating new objects
  2. You don't have to worry about typing new, making syntax simpler (but perhaps more confusing)
  3. JQuery actually uses a pattern very similar to this! who would've thought! every time you use $(...), this pattern is applied
  4. this seems to be the most suggested(?) way of trying to accomplish this functionality, but This Post suggests that the following code is equivalent (and much simpler to understand):

    var Ctor = function(args){
      var obj = function(args){
        this.foo = bar
      };
      return new obj();
    };
    

    as for why you'd use the less clear version, I'm not quite sure. The only big difference I can see is that in the first version you're creating a Ctor object and in the second version you're creating a obj object. There's one less function definition in the first version, and maybe there's some other benefits I'm not yet seeing. Knowing these two patterns are equivalent, however, gives me a much better understanding as to how the first pattern works.

Siracle
  • 332
  • 2
  • 10
  • Creating the `var obj = function(args){ this.foo = bar }` inside the `Ctor` is really inefficient. Put it outside. In an IIFE, if you want. – Bergi Dec 18 '18 at 22:50
  • A benefit of making `Ctor` the constructor itself will be that `Ctor() instanceof Ctor`. You can achieve that in different ways though, e.g. [following the `jQuery` pattern](https://stackoverflow.com/a/12143833/1048572). – Bergi Dec 18 '18 at 22:52
  • @bergi thanks for being so involved in this question; I ended up using something like this: `var Ctor = function(args){ if(!this || this === window) return new Ctor(args); function privateConstructor(args){/*...*/}; privateConstructor(args) return this; }` (sorry about the crap formatting..), anyway, Ctor() instanceof Ctor is true in this case I think, there's no separate nested class, and no IIFE. – Siracle Dec 19 '18 at 23:07