1

I opened a javascript project called Jibberish (https://github.com/mdp/gibberish-aes) and I tried to understand it's coding style, I just give a portion of it's start and end:

(function (root, factory) {
    if (typeof exports === 'object') {
        // Node. 
        module.exports = factory();
    } else if (typeof define === 'function' && define.amd) {
        // AMD. Register as an anonymous module.
        define(factory);
    } else {
        // Browser globals (root is window)
        root.GibberishAES = factory();
    }
}(this, function () {
    'use strict';
    var Nr = 14,
    /* Default to 256 Bit Encryption */
    Nk = 8,
    Decrypt = false,
    enc_utf8 = function(s)
    {
        try {
            return unescape(encodeURIComponent(s));
        }
        catch(e) {
            throw 'Error on UTF-8 encode';
        }
    },
    //...................................
    return {
        "size": size,
        "h2a":h2a,
        "expandKey":expandKey,
        "encryptBlock":encryptBlock,
        "decryptBlock":decryptBlock,
        "Decrypt":Decrypt,
        "s2a":s2a,
        "rawEncrypt":rawEncrypt,
        "rawDecrypt":rawDecrypt,
        "dec":dec,
        "openSSLKey":openSSLKey,
        "a2h":a2h,
        "enc":enc,
        "Hash":{"MD5":MD5},
        "Base64":Base64
    };
}));

Just to have an idea of it's usage:

// GibberishAES.enc(string, password)
// Defaults to 256 bit encryption
enc = GibberishAES.enc("This sentence is super secret", "ultra-strong-password");
alert(enc);
GibberishAES.dec(enc, "ultra-strong-password");

I can see an outmost self-executing function returning an object at the end of the code which in fact is anonymous(!) and the members of this object are the functions defined inside the self-executing function so, property "size" refers to function size() defined as a function expression:

size = function(newsize){...}

I can even recall all the discussions about private and public functions of such approach by calling all the returned functions as public and the rest as private but there are some things that puzzle me a lot:

  1. why the outer anonymous function has arguments and where are they going to be used?

  2. instead of (function(){//put my code here...}()); author used (function(root, factory){//some code...}(this, function(){//main code here...}));, why was that?

  3. On question (2) I can see two arguments this and function(){//main code here...} passed as arguments to the outer anonymous function in place of root and factory. So, root became this! But, now where this is referring to?

  4. Maybe we could achieve a better rewrite of all this or not? I just read How do I declare a namespace in JavaScript? and I find Jaco Pretorius answer so great that I can rewrite this one and add it to my namespace like so:

    (function(myGibberishAES){

    //main code here...

    }(window.myGibberishAES = window.myGibberishAES || {}));

Is this ok with acceptable coding standards?

Thanks!

Community
  • 1
  • 1
centurian
  • 1,168
  • 13
  • 25
  • ...and at the same post (http://stackoverflow.com/questions/881515/javascript-namespace-declaration) combining Jaco Pretorius answer with Fentex I can be even more creative: `mynamespace = window.mynamespace || {};` and then `mynamespace.GibberishAES = (function(){//main code here..}());` or I can do better??? – centurian Apr 19 '13 at 17:29

1 Answers1

2

This format is called UMD (Universal Module Definition), and it is a way to write code that can work with and without AMD (Asynchronous Module Definition), and with and without Node.

In the first anonymous function, the code is checking to see what environment we're in.

  1. If an exports function is defined, then we're probably using node.js
  2. If there is a function called define, and it has a property called amd, then it means that we are using AMD.
  3. If none of the above cases holds true, we're not using anything so we should attach this to the root object, which in this particular case will be window.

The arguments to this function are this (which will be window) and a function that is basically a factory, i.e., it is the code that actually defines your object. Normally (without UMD), it would look like this:

var myModule = (function() {
    ...
}();

So now factory is basically this function, which returns your module/object. This object can be assigned to either module.exports if you are using node.js, or it can be passed into the define function if you are using AMD, or otherwise you can simply attach it to the root object (window).

As far as your question of a rewrite, you probably do not want to do this because the regular JavaScript Namespace Declaration pattern will not work with node.js and AMD. AMD, which is used with requireJS lets you specify and manage dependencies and so if someone is using requireJS, this allows them to import this module quite easily. This is basically a way to satisfy three different use-cases and frameworks.

If you are not using node.js or requireJS, you don't need to rewrite anything, since GibberishAES will be a global object that is attached to window, and so you can directly use it.

For more information, check out UMD on GitHub, which has a bunch of patterns (what you're looking at is a combination of nideAdapter.js and a simpler variation of amdWeb.js), and also look at AMD on requireJS.

Vivin Paliath
  • 94,126
  • 40
  • 223
  • 295
  • I haven't used node.js before or requireJS but I can tell that this project is aimed to work (and) at the client part, i.e. doing arithmetic at a user's browser! `this` referes to `window` at the global namespace, thanks for reminding this! – centurian Apr 19 '13 at 17:42
  • @centurian I was also confused when I first encountered this pattern. I have an open-source project of my own and a contributor recently modified it to support AMD. That is when I became familiar with this pattern. :) – Vivin Paliath Apr 19 '13 at 17:43