5

I have been studying framework development for a few weeks, and I ran across what is highly suggested and pressured in the world of lib development, Immediately-invoking Anonymous Functions.

I never can get it to work, and I have failed to find a resource that explains in-detail the use and logic behind it.

Here's what I know so far:

  • It's immediately invoking - It runs everything anonymously, immediately.
  • It's anonymous - It does not carry a name therefore the code inside of it is not "reachable" by exterior code.
  • You can pass global window, object and undefined parameters - That's about all I know on that, but do not understand them completely.

I am looking not only for a detailed resource, but one that explains the logic behind it. Because I find it very illogical.

Here's what I have:

(function( window, document, undefined ) {
    window.myThingy = myThingy;

    var myThingy = function() {
    };

    myThingy.prototype = {
        constructor: myThingy,
        create: function( elementToBeCreated ) {
            return document.createElement( elementToBeCreated );
        }
    };

})( window, document );

Then,

myThingy().create("div");

But it is still saying myThingy() [object] is not a function.

What am I doing wrong? Why should I use immediately-invoking functions and not just create a global myThingy = function() object? Why do I have to use window?

I know there are several resources on the net about this, but I can't understand any of it. Some of them go half-way into detail, some of them try to go into detail, but fail to explain the critical stuff. Why is this so stressed when developing a framework?

Don't worry, I'm not trying to "re-invent the wheel", but I am trying, however, to actually learn JavaScript, not just the pre-packaged stuff.

A good answer should contain:

  • A good resource where it explains the logic behind immediately invoking anonymous functions
  • An insight to that link
  • What I am doing wrong with the code I provided
Cœur
  • 37,241
  • 25
  • 195
  • 267
ModernDesigner
  • 7,539
  • 10
  • 34
  • 41
  • 2
    this might help: http://benalman.com/news/2010/11/immediately-invoked-function-expression/ – jbabey Jan 25 '13 at 20:09
  • 1
    You have scope issues. window.myThingy = myThingy; var myThingy = function() { };. The var redeclares myThingy to local scope. Remove the var. – scrappedcola Jan 25 '13 at 20:09
  • 4
    They're not really "self-invoking". A better term is "Immediately Invoked Function Expression" (IIFE). – Pointy Jan 25 '13 at 20:14
  • 1
    @scrappedcola: the var declaration doesn't remove the assignment to window – Jim Deville Jan 25 '13 at 20:20
  • @jbabey That is a good reference, and what I prefer is the "Module Pattern", as stated in that article. So I guess it's MP vs. IIFE. – ModernDesigner Jan 25 '13 at 20:23
  • @ModernDesigner - Module Pattern is a pattern that uses IIFE, not an alternative. – Jim Deville Jan 25 '13 at 20:23
  • Okay, so the method is the same, but the syntax is different. So what about IIFE using "`prototype`" and then exposing your object to global `window`? That's not even necessary if you're using the module pattern. – ModernDesigner Jan 25 '13 at 20:27
  • 1
    @ModernDesigner a "revealing module pattern" uses an IIFE to construct itself, but it is not synonomous to an IIFE. – jbabey Jan 25 '13 at 20:33
  • using prototype and attaching to window is not IIFE, IIFE is _only_ the concept of `(function() {})()`. Passing `window`,`document`, etc, and everything you do inside of that function are orthogonal. – Jim Deville Jan 25 '13 at 20:33
  • possible duplicate of [What advantages does using (function(window, document, undefined) { ... })(window, document) confer?](http://stackoverflow.com/questions/5020479/what-advantages-does-using-functionwindow-document-undefined-windo) – Bergi Aug 01 '13 at 00:39

2 Answers2

4

First off, you have not yet defined your function when you try to assign it to the global object so it is undefined:

window.myThingy = myThingy;
console.log(myThingy);//undefined

You need to do the assignment after myThingy is defined:

(function( window, document, undefined ) {


 var myThingy = function() {
 };

 myThingy.prototype = {
    constructor: myThingy,
    create: function( elementToBeCreated ) {
        return document.createElement( elementToBeCreated );
    }
 };

 window.myThingy = myThingy;

})( window, document );

Okay, next, you cannot use

myThingy.create("div");

because myThingy is a function and not an object. Function objects are created when the new keyword is issued to a function. You can make this change to convert your function into a function object:

window.myThingy = new myThingy();//create a function object

This pattern is not how all frameworks are implemented, but similar. Sometimes there is more abstraction. However, making these changes will allow your approach to work.

Here is a demo of your code: http://jsfiddle.net/ZjRJW/


Links

Here are some of my favorites:

http://ejohn.org/blog/simple-class-instantiation/

http://ejohn.org/apps/learn/

http://ejohn.org/blog/simple-javascript-inheritance/

http://jibbering.com/faq/notes/closures/

https://developer.mozilla.org/en-US/docs/JavaScript/Guide/Details_of_the_Object_Model

http://javascript.crockford.com/prototypal.html

Travis J
  • 81,153
  • 41
  • 202
  • 273
  • 2
    Wow, I like your resources! As far as the code correction, I see what you mean by it's a function, not an object. Doh! That's what Chrome's error console has been returning every time. Thanks for pointing that out. I do think you have solved my problem. As far as accepting this answer; this, in conjunction with the comments above, has fulfilled my curiosity. I'll be doing a lot of homework on those resources though, thanks! – ModernDesigner Jan 25 '13 at 20:37
2

If you want to learn about JS design patterns, I highly recommend Addy Osmani's books/articles. He keeps things very simple and usually supplies quite a bit of example code to help you understand. As far as your code and implementing a design pattern is concerned, it depends on what you want your code to do, and how you want your code/objects to behave. Understanding your requirements/goals are very important before you start coding so you don't get lost in a spaghetti of patterns that really aren't solving a specific problem.

In some cases, implementing a pattern intended for a complex, large application is simply overkill.

Since someone else already correctly pointed out the issues with your code, I'll just leave it there.

Bryan A
  • 3,598
  • 1
  • 23
  • 29